diff --git a/.chglog/README.md b/.chglog/README.md index eb0b0af63..7c81e3bd5 100644 --- a/.chglog/README.md +++ b/.chglog/README.md @@ -8,7 +8,7 @@ It is possible to test the tool by `git-chglog --init` without overriding anythi ## Usage -Example for a new release "v2.1.1": +Example for a new release "v2.2.0": ```sh git checkout release @@ -16,14 +16,14 @@ git pull git fetch --tags git checkout dev git pull upstream dev -git checkout -b rel/prepare_for_release_v211 -git-chglog --config .chglog/config_gobot.yml --no-case --next-tag v2.1.1 v2.1.0.. > .chglog/chglog_tmp.md +git checkout -b rel/prepare_for_release_v220 +git-chglog --config .chglog/config_gobot.yml --no-case --next-tag v2.2.0 v2.1.1.. > .chglog/chglog_tmp.md ``` ## Compare If unsure about any result of running git-chglog, just use: -`git log --since=2023-05-28 --pretty="- %s"` +`git log --since=2023-07-07 --pretty="- %s"` ## Manual adjustment diff --git a/.chglog/config_gobot.yml b/.chglog/config_gobot.yml index cd54029c9..fe03802f1 100755 --- a/.chglog/config_gobot.yml +++ b/.chglog/config_gobot.yml @@ -5,7 +5,7 @@ info: repository_url: https://github.com/hybridgroup/gobot options: header: - pattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:?\\s(.*)$" + pattern: "^(\\w*)(?:\\(([\\w\\$\\.\\,\\-\\*\\s]*)\\))?\\:?\\s(.*)$" pattern_maps: - Type - Scope diff --git a/.circleci/config.yml b/.circleci/config.yml index 2727f9153..c3b40f46b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,7 +14,7 @@ version: 2 jobs: "test_core_and_drivers_with_coverage": docker: - - image: cimg/go:1.18 + - image: cimg/go:1.19 steps: - checkout - run: @@ -31,32 +31,32 @@ jobs: "test_platforms": docker: - - image: cimg/go:1.18 + - image: cimg/go:1.19 steps: - checkout - run: name: Debug version command: go version - run: - # digispark needs libusb, joystick needs sdl2, opencv needs opencv - name: Platform tests (except digispark, joystick, opencv) + # digispark needs libusb, opencv needs opencv + name: Platform tests (except digispark and opencv) command: | - go test -v $(go list ./platforms/... | grep -v platforms/digispark | grep -v platforms/joystick | grep -v platforms/opencv) + go test -v $(go list ./platforms/... | grep -v platforms/digispark | grep -v platforms/opencv) "check_examples": docker: - - image: cimg/go:1.18 + - image: cimg/go:1.19 steps: - checkout - run: name: Debug version command: go version - run: - # digispark needs libusb, joystick needs sdl2, opencv needs opencv - name: Check examples (except digispark, joystick, opencv) + # digispark needs libusb, opencv needs opencv + name: Check examples (except digispark, opencv) command: | ALL=$(grep -l -r --include "*.go" 'build example' ./) - SOME=$(grep -L 'digispark' $(grep -L 'joystick' $(grep -L 'gocv' ${ALL}))) + SOME=$(grep -L 'digispark' $(grep -L 'gocv' ${ALL})) for e in ${SOME} ; do go vet "${e}" ; done workflows: diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 6ead6dc19..8b9028ee6 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -15,23 +15,24 @@ jobs: name: lint runs-on: ubuntu-latest steps: + - uses: actions/checkout@v3 - uses: actions/setup-go@v4 with: - go-version: '1.18' + go-version: '1.19' cache: false - - uses: actions/checkout@v3 - name: golangci-lint uses: golangci/golangci-lint-action@v3 with: # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version - version: v1.53.3 + version: v1.54.2 # Optional: working directory, useful for monorepos # working-directory: v2 # Optional: golangci-lint command line arguments. # mostly there is no problem locally, but on server: "could not import C (cgo preprocessing failed) (typecheck)" - args: --skip-files platforms/digispark/littleWire.go + # and the digispark adaptor can not be build since switch to linter version 1.54.2 + args: --skip-files="platforms/digispark/littleWire.go,platforms/digispark/digispark_adaptor.go" # Optional: show only new issues if it's a pull request. The default value is `false`. # only-new-issues: true diff --git a/.golangci.yml b/.golangci.yml index c1b5f1f2e..9b907888c 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -31,9 +31,10 @@ run: linters: # currently active linters: # - #INFO [lintersdb] Active 35 linters: [asasalint asciicheck bidichk contextcheck decorder depguard durationcheck errcheck exportloopref - # gocheckcompilerdirectives gomoddirectives gomodguard goprintffuncname gosimple govet grouper ineffassign makezero mirror musttag - # nilerr nilnil nolintlint nosprintfhostport prealloc reassign revive staticcheck tagalign tenv testableexamples tparallel typecheck unused wastedassign] + #INFO [lintersdb] Active 42 linters: [asasalint asciicheck bidichk contextcheck decorder depguard dupword durationcheck errcheck exportloopref + # gocheckcompilerdirectives gofmt gofumpt goimports gomoddirectives gomodguard goprintffuncname gosec gosimple govet grouper ineffassign makezero mirror + # misspell musttag nilerr nilnil nolintlint nosprintfhostport prealloc reassign revive staticcheck tagalign tenv testableexamples tparallel unconvert unparam + # unused wastedassign] enable-all: true @@ -60,7 +61,6 @@ linters: - godot # not used (seems to be counting peas) - godox # not used (we have many TODOs, so not useful) - goerr113 # not used (we allow error creation at return statement) - - gofumpt # not used (we use "go fmt" or "gofmt" not gofumpt" - gosmopolitan # not needed (report i18n/l10n anti-patterns) - importas # not needed (there is no alias rule at the moment) - ireturn # not used (we allow return interfaces) @@ -73,38 +73,30 @@ linters: - wrapcheck # not needed (we allow errors from interface methods) - zerologlint # not needed (related to zerolog package) # important to have - - gofmt # important to prevent "format tsunami" ("gofmt -s -w" missed), disabled due to "https://github.com/golangci/golangci-lint-action/issues/535" + - errorlint # useful (reduce bugs), but suppress the "Use `%w` to format errors" check + - forcetypeassert # useful (reduce bugs) - nakedret # very useful together with "nonamedreturns" (reduce bugs) - nonamedreturns # very useful (reduce bugs) - - unconvert # very useful (reduce bugs, simplify code) - - unparam # very useful (reduce bugs, simplify code) # useful for the future - bodyclose # maybe useful (reduce bugs), exclusions for tests needed - containedctx # useful (structs are not for context wrapping) - cyclop # useful with some tweeks (better understandable code), see also gocyclo - dogsled # useful with some tweeks (e.g. exclude tests) - dupl # useful with some tweeks (reduce bugs and lines of code) - - dupword # useful with some tweeks, but not important - errchkjson # useful (reduce bugs) - errname # useful for common style - - errorlint # useful (reduce bugs), but suppress the "Use `%w` to format errors" check - exhaustruct # useful with some exclusions for existing code (e.g. mavlink/common/common.go) - - forcetypeassert # useful (reduce bugs) - funlen # useful with some tweeks (reduce bugs, simplify code, better understandable code) - gci # useful (improve readability) - - gochecknoinits # useful (reduce bugs, simplify bug catching) - gocognit # useful with some tweeks (better understandable code) - goconst # useful (reduce bugs) - gocritic # useful with some exclusions for existing code (e.g. mavlink/common/common.go) - gocyclo # useful with some tweeks (better understandable code) - goheader # useful, if we introduce a common header (e.g. for copyright) - - goimports # useful (common style), but not important - gomnd # useful with some exclusions for existing code (e.g. mavlink.go) - - gosec # useful (security) - interfacebloat # useful with some exclusions at usage of external packages - lll # useful with some exclusions for existing code (e.g. mavlink/common/common.go) - maintidx # useful with some tweeks (better understandable code), maybe use instead "gocyclo", "gocognit" , "cyclop" - - misspell # useful (better understandable code), but not important - nestif # useful (reduce bugs, simplify code, better understandable code) - nlreturn # more common style, but could become annoying - noctx # maybe good (show used context explicit) @@ -141,6 +133,15 @@ linters-settings: - pkg: "github.com/pkg/errors" desc: Should be replaced by standard lib errors package + dupword: + # Keywords for detecting duplicate words. + # If this list is not empty, only the words defined in this list will be detected. + # Default: [] + keywords: + - "the" + - "and" + - "a" + nolintlint: # Enable to require an explanation of nonzero length after each nolint directive. # Default: false diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b185e628..3fd63f0a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,61 @@ # CHANGELOG -## [Unreleased](https://github.com/hybridgroup/gobot/compare/v2.1.1...HEAD) +## [Unreleased](https://github.com/hybridgroup/gobot/compare/v2.2.0...HEAD) + +## [v2.2.0](https://github.com/hybridgroup/gobot/compare/v2.1.1...v2.2.0) (2023-10-29) + +### Adaptors + +* **PWM:** fix wrong duty cycle after kill program ([#994](https://github.com/hybridgroup/gobot/issues/994)) + +### Beaglebone + +* **doc:** fix preceding typo ([#985](https://github.com/hybridgroup/gobot/issues/985)) + +### Build + +* **deps:** module update ([#992](https://github.com/hybridgroup/gobot/issues/992)) +* **go, deps:** switch to Go 1.19 and update modules ([#1008](https://github.com/hybridgroup/gobot/issues/1008)) +* **style:** switch to gofumpt and add linters ([#1009](https://github.com/hybridgroup/gobot/issues/1009)) + +### Doc + +* **roadmap:** remove file ROADMAP.md after creating issues ([#1005](https://github.com/hybridgroup/gobot/issues/1005)) + +### Dragonboard + +* fix example and documentation ([#977](https://github.com/hybridgroup/gobot/issues/977)) + +### Gpio + +* **hcsr04:** add driver for ultrasonic ranging module ([#1012](https://github.com/hybridgroup/gobot/issues/1012)) + +### I2c + +* **PCA9685, adafruit, adafruit2327, adafruit2348:** clean up architecture and fix init ([#1021](https://github.com/hybridgroup/gobot/issues/1021)) + +### Jetson + +* **PWM:** fix set period ([#1019](https://github.com/hybridgroup/gobot/issues/1019)) + +### Joystick + +* **core:** replace sdl with 0xcafed00d/joystick package ([#988](https://github.com/hybridgroup/gobot/issues/988)) + +### Sphero + +* Add support for calibration + +### System + +* **gpio:** add edge polling function ([#1015](https://github.com/hybridgroup/gobot/issues/1015)) + +### Test + +* **all:** substitude assert.Nil by assert.NoError if useful ([#1016](https://github.com/hybridgroup/gobot/issues/1016)) +* **all:** substitude assert.Error by assert.ErrorContains ([#1014](https://github.com/hybridgroup/gobot/issues/1014), [#1011](https://github.com/hybridgroup/gobot/issues/1011)) +* **all:** switch to test package stretchr testify ([#1006](https://github.com/hybridgroup/gobot/issues/1006)) +* **gpio, aio:** cleanup helper_test ([#1018](https://github.com/hybridgroup/gobot/issues/1018)) ## [v2.1.1](https://github.com/hybridgroup/gobot/compare/v2.1.0...v2.1.1) (2023-07-07) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ae735ac17..ea1f095ed 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,7 +41,7 @@ Descriptions for each of these will eventually be provided below. from time to time but they can complicate merges and should be done separately. * Take care to maintain the existing coding style. * `golangci-lint` your code, see [instruction for local installation](https://golangci-lint.run/usage/install/#local-installation) -* `go fmt` your code (with the go version of go.mod) +* `gofumpt` your code (the go version will be automatically obtained from go.mod), see [instructions](https://github.com/mvdan/gofumpt/blob/master/README.md) * Add unit tests for any new or changed functionality. * All pull requests should be "fast forward" * If there are commits after yours use “git rebase -i ” diff --git a/Makefile b/Makefile index 4d7c4b56d..b83504e45 100644 --- a/Makefile +++ b/Makefile @@ -2,12 +2,8 @@ ALL_EXAMPLES := $(shell grep -l -r --include "*.go" 'build example' ./) # prevent examples with gocv (opencv) dependencies EXAMPLES_NO_GOCV := $(shell grep -L 'gocv' $(ALL_EXAMPLES)) -# prevent examples with joystick (sdl2) dependencies -EXAMPLES_NO_JOYSTICK := $(shell grep -L 'joystick' $(ALL_EXAMPLES)) -# prevent examples with joystick (sdl2) and gocv (opencv) dependencies -EXAMPLES_NO_GOCV_JOYSTICK := $(shell grep -L 'joystick' $$(grep -L 'gocv' $(EXAMPLES_NO_GOCV))) # used examples -EXAMPLES := $(EXAMPLES_NO_GOCV_JOYSTICK) +EXAMPLES := $(EXAMPLES_NO_GOCV) .PHONY: test test_race test_cover robeaux version_check fmt_check fmt_fix examples examples_check $(EXAMPLES) @@ -54,14 +50,14 @@ version_check: echo "go: $${gv}.*, go.mod: $${mv}" ; \ if [ "$${gv}" != "$${mv}" ]; then exit 50; fi ; \ -# Check for bad code style and other issues +# Check for bad code style and other issues (gofumpt and gofmt check is activated for the linter) fmt_check: - gofmt -l -s . golangci-lint run -v -# Fix bad code style (will only be executed, on version match) -fmt_fix: version_check - gofmt -l -s -w . +# Fix bad code style (the go version will be automatically obtained from go.mod) +fmt_fix: + $(MAKE) version_check || true + gofumpt -l -w . examples: $(EXAMPLES) diff --git a/README.md b/README.md index 560c40eb4..8a1a4310a 100644 --- a/README.md +++ b/README.md @@ -270,7 +270,7 @@ Support for many devices that use General Purpose Input/Output (GPIO) have a shared set of drivers provided using the `gobot/drivers/gpio` package: - [GPIO](https://en.wikipedia.org/wiki/General_Purpose_Input/Output) <=> [Drivers](https://github.com/hybridgroup/gobot/tree/master/drivers/gpio) - - AIP1640 LED + - AIP1640 LED Dot Matrix/7 Segment Controller - Button - Buzzer - Direct Pin @@ -281,8 +281,11 @@ a shared set of drivers provided using the `gobot/drivers/gpio` package: - Grove Magnetic Switch - Grove Relay - Grove Touch Sensor + - HC-SR04 Ultrasonic Ranging Module + - HD44780 LCD controller - LED - Makey Button + - MAX7219 LED Dot Matrix - Motor - Proximity Infra Red (PIR) Motion Sensor - Relay @@ -306,8 +309,9 @@ Support for devices that use Inter-Integrated Circuit (I2C) have a shared set of drivers provided using the `gobot/drivers/i2c` package: - [I2C](https://en.wikipedia.org/wiki/I%C2%B2C) <=> [Drivers](https://github.com/hybridgroup/gobot/tree/master/drivers/i2c) - - Adafruit 2x16 RGB-LCD with 5 keys - - Adafruit Motor Hat + - Adafruit 1109 2x16 RGB-LCD with 5 keys + - Adafruit 2327 16-Channel PWM/Servo HAT Hat + - Adafruit 2348 DC and Stepper Motor Hat - ADS1015 Analog to Digital Converter - ADS1115 Analog to Digital Converter - ADXL345 Digital Accelerometer diff --git a/ROADMAP.md b/ROADMAP.md deleted file mode 100644 index fb199b62b..000000000 --- a/ROADMAP.md +++ /dev/null @@ -1,56 +0,0 @@ -# Roadmap - -This is the roadmap of what we as a community want to see happen with Gobot. It should be considered more as a statement of direction then a list of tasks. - -Requests for changes to the roadmap should be made in the form of pull requests to this document. - -Anything tied to any implementation, including requests for platform support, bug reports, or other specifics should still be made by creating a new issue here: - - - -## core - -- standardized logging -- use Context to allow for graceful exits. - -## api - -- ability to plug in your own router to handle API calls, for example to serve a custom web app. -- restrict API calls to only specific set of entrypoints. -- serve other transports/protocols other than HTTP/REST for example CoAP. - -## gpio - -- support for epoll/interrupt based gpio events. -- helper method for interrupts to handle "ping" timing-based devices. -- Windows 10 support. -- use variadic constructor functions to allow for additional params, similar to i2c drivers. - -## aio - -- support for epoll based aio events possible? -- Windows 10 support. -- use variadic constructor functions to allow for additional params, similar to i2c drivers. - -## i2c - -add support for the following i2c devices: - -- MAG3110 -- MMA8452 -- T5403 -- TMP006 -- VCNL4000 - -## 1-wire - -- add support for 1-wire protocol. - -## serial - -- create a common serial Adaptor, so different serial devices such as GPS, LIDAR etc only need to implement drivers. - -## ble - -- improve the ble package to allow support for multiple peripherals. -- Windows 10 support. diff --git a/adaptor.go b/adaptor.go index ef7d4e42c..81c6919a4 100644 --- a/adaptor.go +++ b/adaptor.go @@ -21,12 +21,18 @@ type DigitalPinOptioner interface { SetDrive(drive int) (changed bool) // SetDebounce initializes the input pin with the given debounce period. SetDebounce(period time.Duration) (changed bool) - // SetEventHandlerForEdge initializes the input pin for edge detection and to call the event handler on specified edge. + // SetEventHandlerForEdge initializes the input pin for edge detection to call the event handler on specified edge. // lineOffset is within the GPIO chip (needs to transformed to the pin id), timestamp is the detection time, // detectedEdge contains the direction of the pin changes, seqno is the sequence number for this event in the sequence // of events for all the lines in this line request, lseqno is the same but for this line SetEventHandlerForEdge(handler func(lineOffset int, timestamp time.Duration, detectedEdge string, seqno uint32, lseqno uint32), edge int) (changed bool) + // SetPollForEdgeDetection use a discrete input polling method to detect edges. A poll interval of zero or smaller + // will deactivate this function. Please note: Using this feature is CPU consuming and less accurate than using cdev + // event handler (gpiod implementation) and should be done only if the former is not implemented or not working for + // the adaptor. E.g. sysfs driver in gobot has not implemented edge detection yet. The function is only useful + // together with SetEventHandlerForEdge() and its corresponding With*() functions. + SetPollForEdgeDetection(pollInterval time.Duration, pollQuitChan chan struct{}) (changed bool) } // DigitalPinOptionApplier is the interface to apply options to change pin behavior immediately @@ -109,7 +115,6 @@ type PWMPinnerProvider interface { // Data (8 bits): A plain data byte. DataLow and DataHigh represent the low and high byte of a 16 bit word. // Count (8 bits): A data byte containing the length of a block operation. // [..]: Data sent by I2C device, as opposed to data sent by the host adapter. -// type I2cSystemDevicer interface { // ReadByte must be implemented as the sequence: // "S Addr Rd [A] [Data] NA P" diff --git a/api/api.go b/api/api.go index 365d59e8f..448f2f8e2 100644 --- a/api/api.go +++ b/api/api.go @@ -8,6 +8,7 @@ import ( "net/http" "net/http/httptest" "strings" + "time" "github.com/bmizerany/pat" "gobot.io/x/gobot/v2" @@ -35,16 +36,20 @@ func NewAPI(m *gobot.Master) *API { start: func(a *API) { log.Println("Initializing API on " + a.Host + ":" + a.Port + "...") http.Handle("/", a) + server := &http.Server{ + Addr: a.Host + ":" + a.Port, + ReadHeaderTimeout: 30 * time.Second, + } go func() { if a.Cert != "" && a.Key != "" { - if err := http.ListenAndServeTLS(a.Host+":"+a.Port, a.Cert, a.Key, nil); err != nil { + if err := server.ListenAndServeTLS(a.Cert, a.Key); err != nil { panic(err) } } else { log.Println("WARNING: API using insecure connection. " + "We recommend using an SSL certificate with Gobot.") - if err := http.ListenAndServe(a.Host+":"+a.Port, nil); err != nil { + if err := server.ListenAndServe(); err != nil { panic(err) } } @@ -313,7 +318,6 @@ func (a *API) robotConnections(res http.ResponseWriter, req *http.Request) { } else { a.writeJSON(map[string]interface{}{"error": "No Robot found with the name " + req.URL.Query().Get(":robot")}, res) } - } // robotConnection returns connection route handler @@ -369,7 +373,6 @@ func (a *API) executeCommand(f func(map[string]interface{}) interface{}, res http.ResponseWriter, req *http.Request, ) { - body := make(map[string]interface{}) if err := json.NewDecoder(req.Body).Decode(&body); err != nil { panic(err) diff --git a/api/api_test.go b/api/api_test.go index e7d0ce404..477bb298c 100644 --- a/api/api_test.go +++ b/api/api_test.go @@ -11,8 +11,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) func initTestAPI() *API { @@ -46,7 +46,7 @@ func TestStartWithoutDefaults(t *testing.T) { request, _ := http.NewRequest("GET", "/", nil) response := httptest.NewRecorder() a.ServeHTTP(response, request) - gobottest.Assert(t, response.Code, 200) + assert.Equal(t, 200, response.Code) } func TestRobeaux(t *testing.T) { @@ -55,22 +55,22 @@ func TestRobeaux(t *testing.T) { request, _ := http.NewRequest("GET", "/index.html", nil) response := httptest.NewRecorder() a.ServeHTTP(response, request) - gobottest.Assert(t, response.Code, 200) + assert.Equal(t, 200, response.Code) // js assets request, _ = http.NewRequest("GET", "/js/script.js", nil) response = httptest.NewRecorder() a.ServeHTTP(response, request) - gobottest.Assert(t, response.Code, 200) + assert.Equal(t, 200, response.Code) // css assets request, _ = http.NewRequest("GET", "/css/application.css", nil) response = httptest.NewRecorder() a.ServeHTTP(response, request) - gobottest.Assert(t, response.Code, 200) + assert.Equal(t, 200, response.Code) // unknown asset request, _ = http.NewRequest("GET", "/js/fake/file.js", nil) response = httptest.NewRecorder() a.ServeHTTP(response, request) - gobottest.Assert(t, response.Code, 404) + assert.Equal(t, 404, response.Code) } func TestIndex(t *testing.T) { @@ -80,8 +80,8 @@ func TestIndex(t *testing.T) { a.ServeHTTP(response, request) - gobottest.Assert(t, http.StatusMovedPermanently, response.Code) - gobottest.Assert(t, "/index.html", response.Header()["Location"][0]) + assert.Equal(t, response.Code, http.StatusMovedPermanently) + assert.Equal(t, response.Header()["Location"][0], "/index.html") } func TestMcp(t *testing.T) { @@ -92,8 +92,8 @@ func TestMcp(t *testing.T) { var body map[string]interface{} _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Refute(t, body["MCP"].(map[string]interface{})["robots"], nil) - gobottest.Refute(t, body["MCP"].(map[string]interface{})["commands"], nil) + assert.NotNil(t, body["MCP"].(map[string]interface{})["robots"]) + assert.NotNil(t, body["MCP"].(map[string]interface{})["commands"]) } func TestMcpCommands(t *testing.T) { @@ -104,7 +104,7 @@ func TestMcpCommands(t *testing.T) { var body map[string]interface{} _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, body["commands"], []interface{}{"TestFunction"}) + assert.Equal(t, []interface{}{"TestFunction"}, body["commands"]) } func TestExecuteMcpCommand(t *testing.T) { @@ -121,7 +121,7 @@ func TestExecuteMcpCommand(t *testing.T) { a.ServeHTTP(response, request) _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, body.(map[string]interface{})["result"], "hey Beep Boop") + assert.Equal(t, "hey Beep Boop", body.(map[string]interface{})["result"]) // unknown command request, _ = http.NewRequest("GET", @@ -133,7 +133,7 @@ func TestExecuteMcpCommand(t *testing.T) { a.ServeHTTP(response, request) _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, body.(map[string]interface{})["error"], "Unknown Command") + assert.Equal(t, "Unknown Command", body.(map[string]interface{})["error"]) } func TestRobots(t *testing.T) { @@ -144,7 +144,7 @@ func TestRobots(t *testing.T) { var body map[string]interface{} _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, len(body["robots"].([]interface{})), 3) + assert.Equal(t, 3, len(body["robots"].([]interface{}))) } func TestRobot(t *testing.T) { @@ -157,14 +157,14 @@ func TestRobot(t *testing.T) { var body map[string]interface{} _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, body["robot"].(map[string]interface{})["name"].(string), "Robot1") + assert.Equal(t, "Robot1", body["robot"].(map[string]interface{})["name"].(string)) // unknown robot request, _ = http.NewRequest("GET", "/api/robots/UnknownRobot1", nil) a.ServeHTTP(response, request) _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, body["error"], "No Robot found with the name UnknownRobot1") + assert.Equal(t, "No Robot found with the name UnknownRobot1", body["error"]) } func TestRobotDevices(t *testing.T) { @@ -177,14 +177,14 @@ func TestRobotDevices(t *testing.T) { var body map[string]interface{} _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, len(body["devices"].([]interface{})), 3) + assert.Equal(t, 3, len(body["devices"].([]interface{}))) // unknown robot request, _ = http.NewRequest("GET", "/api/robots/UnknownRobot1/devices", nil) a.ServeHTTP(response, request) _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, body["error"], "No Robot found with the name UnknownRobot1") + assert.Equal(t, "No Robot found with the name UnknownRobot1", body["error"]) } func TestRobotCommands(t *testing.T) { @@ -197,14 +197,14 @@ func TestRobotCommands(t *testing.T) { var body map[string]interface{} _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, body["commands"], []interface{}{"robotTestFunction"}) + assert.Equal(t, []interface{}{"robotTestFunction"}, body["commands"]) // unknown robot request, _ = http.NewRequest("GET", "/api/robots/UnknownRobot1/commands", nil) a.ServeHTTP(response, request) _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, body["error"], "No Robot found with the name UnknownRobot1") + assert.Equal(t, "No Robot found with the name UnknownRobot1", body["error"]) } func TestExecuteRobotCommand(t *testing.T) { @@ -220,7 +220,7 @@ func TestExecuteRobotCommand(t *testing.T) { a.ServeHTTP(response, request) _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, body.(map[string]interface{})["result"], "hey Robot1, Beep Boop") + assert.Equal(t, "hey Robot1, Beep Boop", body.(map[string]interface{})["result"]) // unknown command request, _ = http.NewRequest("GET", @@ -232,7 +232,7 @@ func TestExecuteRobotCommand(t *testing.T) { a.ServeHTTP(response, request) _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, body.(map[string]interface{})["error"], "Unknown Command") + assert.Equal(t, "Unknown Command", body.(map[string]interface{})["error"]) // uknown robot request, _ = http.NewRequest("GET", @@ -243,7 +243,7 @@ func TestExecuteRobotCommand(t *testing.T) { a.ServeHTTP(response, request) _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, body.(map[string]interface{})["error"], "No Robot found with the name UnknownRobot1") + assert.Equal(t, "No Robot found with the name UnknownRobot1", body.(map[string]interface{})["error"]) } func TestRobotDevice(t *testing.T) { @@ -259,7 +259,7 @@ func TestRobotDevice(t *testing.T) { var body map[string]interface{} _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, body["device"].(map[string]interface{})["name"].(string), "Device1") + assert.Equal(t, "Device1", body["device"].(map[string]interface{})["name"].(string)) // unknown device request, _ = http.NewRequest("GET", @@ -267,7 +267,7 @@ func TestRobotDevice(t *testing.T) { a.ServeHTTP(response, request) _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, body["error"], "No Device found with the name UnknownDevice1") + assert.Equal(t, "No Device found with the name UnknownDevice1", body["error"]) } func TestRobotDeviceCommands(t *testing.T) { @@ -283,7 +283,7 @@ func TestRobotDeviceCommands(t *testing.T) { var body map[string]interface{} _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, len(body["commands"].([]interface{})), 2) + assert.Equal(t, 2, len(body["commands"].([]interface{}))) // unknown device request, _ = http.NewRequest("GET", @@ -292,7 +292,7 @@ func TestRobotDeviceCommands(t *testing.T) { ) a.ServeHTTP(response, request) _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, body["error"], "No Device found with the name UnknownDevice1") + assert.Equal(t, "No Device found with the name UnknownDevice1", body["error"]) } func TestExecuteRobotDeviceCommand(t *testing.T) { @@ -309,7 +309,7 @@ func TestExecuteRobotDeviceCommand(t *testing.T) { a.ServeHTTP(response, request) _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, body.(map[string]interface{})["result"].(string), "hello human") + assert.Equal(t, "hello human", body.(map[string]interface{})["result"].(string)) // unknown command request, _ = http.NewRequest("GET", @@ -321,7 +321,7 @@ func TestExecuteRobotDeviceCommand(t *testing.T) { a.ServeHTTP(response, request) _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, body.(map[string]interface{})["error"], "Unknown Command") + assert.Equal(t, "Unknown Command", body.(map[string]interface{})["error"]) // unknown device request, _ = http.NewRequest("GET", @@ -332,8 +332,7 @@ func TestExecuteRobotDeviceCommand(t *testing.T) { a.ServeHTTP(response, request) _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, body.(map[string]interface{})["error"], "No Device found with the name UnknownDevice1") - + assert.Equal(t, "No Device found with the name UnknownDevice1", body.(map[string]interface{})["error"]) } func TestRobotConnections(t *testing.T) { @@ -346,14 +345,14 @@ func TestRobotConnections(t *testing.T) { var body map[string]interface{} _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, len(body["connections"].([]interface{})), 3) + assert.Equal(t, 3, len(body["connections"].([]interface{}))) // unknown robot request, _ = http.NewRequest("GET", "/api/robots/UnknownRobot1/connections", nil) a.ServeHTTP(response, request) _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, body["error"], "No Robot found with the name UnknownRobot1") + assert.Equal(t, "No Robot found with the name UnknownRobot1", body["error"]) } func TestRobotConnection(t *testing.T) { @@ -369,7 +368,7 @@ func TestRobotConnection(t *testing.T) { var body map[string]interface{} _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, body["connection"].(map[string]interface{})["name"].(string), "Connection1") + assert.Equal(t, "Connection1", body["connection"].(map[string]interface{})["name"].(string)) // unknown connection request, _ = http.NewRequest("GET", @@ -378,7 +377,7 @@ func TestRobotConnection(t *testing.T) { ) a.ServeHTTP(response, request) _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, body["error"], "No Connection found with the name UnknownConnection1") + assert.Equal(t, "No Connection found with the name UnknownConnection1", body["error"]) } func TestRobotDeviceEvent(t *testing.T) { @@ -412,7 +411,7 @@ func TestRobotDeviceEvent(t *testing.T) { case resp := <-respc: reader := bufio.NewReader(resp.Body) data, _ := reader.ReadString('\n') - gobottest.Assert(t, data, "data: \"event-data\"\n") + assert.Equal(t, "data: \"event-data\"\n", data) done = true case <-time.After(100 * time.Millisecond): t.Error("Not receiving data") @@ -427,7 +426,7 @@ func TestRobotDeviceEvent(t *testing.T) { var body map[string]interface{} _ = json.NewDecoder(response.Body).Decode(&body) - gobottest.Assert(t, body["error"], "No Event found with the name UnknownEvent") + assert.Equal(t, "No Event found with the name UnknownEvent", body["error"]) } func TestAPIRouter(t *testing.T) { @@ -437,35 +436,35 @@ func TestAPIRouter(t *testing.T) { request, _ := http.NewRequest("HEAD", "/test", nil) response := httptest.NewRecorder() a.ServeHTTP(response, request) - gobottest.Assert(t, response.Code, 200) + assert.Equal(t, 200, response.Code) a.Get("/test", func(res http.ResponseWriter, req *http.Request) {}) request, _ = http.NewRequest("GET", "/test", nil) response = httptest.NewRecorder() a.ServeHTTP(response, request) - gobottest.Assert(t, response.Code, 200) + assert.Equal(t, 200, response.Code) a.Post("/test", func(res http.ResponseWriter, req *http.Request) {}) request, _ = http.NewRequest("POST", "/test", nil) response = httptest.NewRecorder() a.ServeHTTP(response, request) - gobottest.Assert(t, response.Code, 200) + assert.Equal(t, 200, response.Code) a.Put("/test", func(res http.ResponseWriter, req *http.Request) {}) request, _ = http.NewRequest("PUT", "/test", nil) response = httptest.NewRecorder() a.ServeHTTP(response, request) - gobottest.Assert(t, response.Code, 200) + assert.Equal(t, 200, response.Code) a.Delete("/test", func(res http.ResponseWriter, req *http.Request) {}) request, _ = http.NewRequest("DELETE", "/test", nil) response = httptest.NewRecorder() a.ServeHTTP(response, request) - gobottest.Assert(t, response.Code, 200) + assert.Equal(t, 200, response.Code) a.Options("/test", func(res http.ResponseWriter, req *http.Request) {}) request, _ = http.NewRequest("OPTIONS", "/test", nil) response = httptest.NewRecorder() a.ServeHTTP(response, request) - gobottest.Assert(t, response.Code, 200) + assert.Equal(t, 200, response.Code) } diff --git a/api/basic_auth_test.go b/api/basic_auth_test.go index acf0aa3cf..f00033f0c 100644 --- a/api/basic_auth_test.go +++ b/api/basic_auth_test.go @@ -5,7 +5,7 @@ import ( "net/http/httptest" "testing" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) func TestBasicAuth(t *testing.T) { @@ -17,11 +17,11 @@ func TestBasicAuth(t *testing.T) { request.SetBasicAuth("admin", "password") response := httptest.NewRecorder() a.ServeHTTP(response, request) - gobottest.Assert(t, response.Code, 200) + assert.Equal(t, 200, response.Code) request, _ = http.NewRequest("GET", "/api/", nil) request.SetBasicAuth("admin", "wrongPassword") response = httptest.NewRecorder() a.ServeHTTP(response, request) - gobottest.Assert(t, response.Code, 401) + assert.Equal(t, 401, response.Code) } diff --git a/api/cors_test.go b/api/cors_test.go index 0e63674f6..cfd60eeb7 100644 --- a/api/cors_test.go +++ b/api/cors_test.go @@ -5,7 +5,7 @@ import ( "net/http/httptest" "testing" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) func TestCORSIsOriginAllowed(t *testing.T) { @@ -13,50 +13,50 @@ func TestCORSIsOriginAllowed(t *testing.T) { cors.generatePatterns() // When all the origins are accepted - gobottest.Assert(t, cors.isOriginAllowed("http://localhost:8000"), true) - gobottest.Assert(t, cors.isOriginAllowed("http://localhost:3001"), true) - gobottest.Assert(t, cors.isOriginAllowed("http://server.com"), true) + assert.True(t, cors.isOriginAllowed("http://localhost:8000")) + assert.True(t, cors.isOriginAllowed("http://localhost:3001")) + assert.True(t, cors.isOriginAllowed("http://server.com")) // When one origin is accepted cors = &CORS{AllowOrigins: []string{"http://localhost:8000"}} cors.generatePatterns() - gobottest.Assert(t, cors.isOriginAllowed("http://localhost:8000"), true) - gobottest.Assert(t, cors.isOriginAllowed("http://localhost:3001"), false) - gobottest.Assert(t, cors.isOriginAllowed("http://server.com"), false) + assert.True(t, cors.isOriginAllowed("http://localhost:8000")) + assert.False(t, cors.isOriginAllowed("http://localhost:3001")) + assert.False(t, cors.isOriginAllowed("http://server.com")) // When several origins are accepted cors = &CORS{AllowOrigins: []string{"http://localhost:*", "http://server.com"}} cors.generatePatterns() - gobottest.Assert(t, cors.isOriginAllowed("http://localhost:8000"), true) - gobottest.Assert(t, cors.isOriginAllowed("http://localhost:3001"), true) - gobottest.Assert(t, cors.isOriginAllowed("http://server.com"), true) + assert.True(t, cors.isOriginAllowed("http://localhost:8000")) + assert.True(t, cors.isOriginAllowed("http://localhost:3001")) + assert.True(t, cors.isOriginAllowed("http://server.com")) // When several origins are accepted within the same domain cors = &CORS{AllowOrigins: []string{"http://*.server.com"}} cors.generatePatterns() - gobottest.Assert(t, cors.isOriginAllowed("http://localhost:8000"), false) - gobottest.Assert(t, cors.isOriginAllowed("http://localhost:3001"), false) - gobottest.Assert(t, cors.isOriginAllowed("http://foo.server.com"), true) - gobottest.Assert(t, cors.isOriginAllowed("http://api.server.com"), true) + assert.False(t, cors.isOriginAllowed("http://localhost:8000")) + assert.False(t, cors.isOriginAllowed("http://localhost:3001")) + assert.True(t, cors.isOriginAllowed("http://foo.server.com")) + assert.True(t, cors.isOriginAllowed("http://api.server.com")) } func TestCORSAllowedHeaders(t *testing.T) { cors := &CORS{AllowOrigins: []string{"*"}, AllowHeaders: []string{"Header1", "Header2"}} - gobottest.Assert(t, cors.AllowedHeaders(), "Header1,Header2") + assert.Equal(t, "Header1,Header2", cors.AllowedHeaders()) } func TestCORSAllowedMethods(t *testing.T) { cors := &CORS{AllowOrigins: []string{"*"}, AllowMethods: []string{"GET", "POST"}} - gobottest.Assert(t, cors.AllowedMethods(), "GET,POST") + assert.Equal(t, "GET,POST", cors.AllowedMethods()) cors.AllowMethods = []string{"GET", "POST", "PUT"} - gobottest.Assert(t, cors.AllowedMethods(), "GET,POST,PUT") + assert.Equal(t, "GET,POST,PUT", cors.AllowedMethods()) } func TestCORS(t *testing.T) { @@ -70,7 +70,7 @@ func TestCORS(t *testing.T) { request.Header.Set("Origin", allowedOrigin[0]) response := httptest.NewRecorder() api.ServeHTTP(response, request) - gobottest.Assert(t, response.Header()["Access-Control-Allow-Origin"], allowedOrigin) + assert.Equal(t, allowedOrigin, response.Header()["Access-Control-Allow-Origin"]) // Not accepted Origin disallowedOrigin := []string{"http://disallowed.com"} @@ -78,6 +78,6 @@ func TestCORS(t *testing.T) { request.Header.Set("Origin", disallowedOrigin[0]) response = httptest.NewRecorder() api.ServeHTTP(response, request) - gobottest.Refute(t, response.Header()["Access-Control-Allow-Origin"], disallowedOrigin) - gobottest.Refute(t, response.Header()["Access-Control-Allow-Origin"], allowedOrigin) + assert.NotEqual(t, disallowedOrigin, response.Header()["Access-Control-Allow-Origin"]) + assert.NotEqual(t, allowedOrigin, response.Header()["Access-Control-Allow-Origin"]) } diff --git a/api/doc.go b/api/doc.go index afc267915..a8e04d3b1 100644 --- a/api/doc.go +++ b/api/doc.go @@ -3,35 +3,35 @@ Package api provides a webserver to interact with your Gobot program over the ne Example: - package main + package main - import ( - "fmt" + import ( + "fmt" - "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/api" - ) + "gobot.io/x/gobot/v2" + "gobot.io/x/gobot/v2/api" + ) - func main() { - gbot := gobot.NewMaster() + func main() { + gbot := gobot.NewMaster() - // Starts the API server on default port 3000 - api.NewAPI(gbot).Start() + // Starts the API server on default port 3000 + api.NewAPI(gbot).Start() - // Accessible via http://localhost:3000/api/commands/say_hello - gbot.AddCommand("say_hello", func(params map[string]interface{}) interface{} { - return "Master says hello!" - }) + // Accessible via http://localhost:3000/api/commands/say_hello + gbot.AddCommand("say_hello", func(params map[string]interface{}) interface{} { + return "Master says hello!" + }) - hello := gbot.AddRobot(gobot.NewRobot("Eve")) + hello := gbot.AddRobot(gobot.NewRobot("Eve")) - // Accessible via http://localhost:3000/api/robots/Eve/commands/say_hello - hello.AddCommand("say_hello", func(params map[string]interface{}) interface{} { - return fmt.Sprintf("%v says hello!", hello.Name) - }) + // Accessible via http://localhost:3000/api/robots/Eve/commands/say_hello + hello.AddCommand("say_hello", func(params map[string]interface{}) interface{} { + return fmt.Sprintf("%v says hello!", hello.Name) + }) - gbot.Start() - } + gbot.Start() + } It follows Common Protocol for Programming Physical Input and Output (CPPP-IO) spec: https://gobot.io/x/cppp-io diff --git a/api/helpers_test.go b/api/helpers_test.go index 0a3336870..7e77d10f6 100644 --- a/api/helpers_test.go +++ b/api/helpers_test.go @@ -64,8 +64,10 @@ type testAdaptor struct { port string } -var testAdaptorConnect = func() (err error) { return } -var testAdaptorFinalize = func() (err error) { return } +var ( + testAdaptorConnect = func() (err error) { return } + testAdaptorFinalize = func() (err error) { return } +) func (t *testAdaptor) Finalize() (err error) { return testAdaptorFinalize() } func (t *testAdaptor) Connect() (err error) { return testAdaptorConnect() } diff --git a/api/robeaux/robeaux.go b/api/robeaux/robeaux.go index 59b5242b1..aeff2c806 100644 --- a/api/robeaux/robeaux.go +++ b/api/robeaux/robeaux.go @@ -86,18 +86,23 @@ type bindataFileInfo struct { func (fi bindataFileInfo) Name() string { return fi.name } + func (fi bindataFileInfo) Size() int64 { return fi.size } + func (fi bindataFileInfo) Mode() os.FileMode { return fi.mode } + func (fi bindataFileInfo) ModTime() time.Time { return fi.modTime } + func (fi bindataFileInfo) IsDir() bool { return false } + func (fi bindataFileInfo) Sys() interface{} { return nil } @@ -916,11 +921,13 @@ var _bindata = map[string]func() (*asset, error){ // directory embedded in the file by go-bindata. // For example if you run go-bindata on data/... and data contains the // following hierarchy: -// data/ -// foo.txt -// img/ -// a.png -// b.png +// +// data/ +// foo.txt +// img/ +// a.png +// b.png +// // then AssetDir("data") would return []string{"foo.txt", "img"} // AssetDir("data/img") would return []string{"a.png", "b.png"} // AssetDir("foo.txt") and AssetDir("notexist") would return an error @@ -1009,7 +1016,7 @@ func RestoreAsset(dir, name string) error { if err != nil { return err } - err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755)) + err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0o755)) if err != nil { return err } diff --git a/appveyor.yml b/appveyor.yml index a2abb7d93..dd9d21df6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -15,7 +15,10 @@ before_test: build_script: - go test -v -cpu=2 . - go test -v -cpu=2 ./drivers/aio/... - - go test -v -cpu=2 ./drivers/i2c/... - - go test -v -cpu=2 ./platforms/firmata/... - go test -v -cpu=2 ./platforms/ble/... + - go test -v -cpu=2 ./platforms/dji/... + - go test -v -cpu=2 ./platforms/firmata/... + - go test -v -cpu=2 ./platforms/joystick/... + - go test -v -cpu=2 ./platforms/parrot/... + - go test -v -cpu=2 ./platforms/sphero/... - cd .. diff --git a/commander_test.go b/commander_test.go index 074581c7a..e73021984 100644 --- a/commander_test.go +++ b/commander_test.go @@ -3,22 +3,18 @@ package gobot import ( "testing" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) -func TestCommaner(t *testing.T) { +func TestCommander(t *testing.T) { + // arrange c := NewCommander() c.AddCommand("test", func(map[string]interface{}) interface{} { return "hi" }) - if _, ok := c.Commands()["test"]; !ok { - t.Errorf("Could not add command to list of Commands") - } - - command := c.Command("test") - gobottest.Refute(t, command, nil) - - command = c.Command("booyeah") - gobottest.Assert(t, command, (func(map[string]interface{}) interface{})(nil)) + // act && assert + assert.Equal(t, 1, len(c.Commands())) + assert.NotNil(t, c.Command("test")) + assert.Nil(t, c.Command("booyeah")) } diff --git a/doc.go b/doc.go index 0d3f92674..ada79dd42 100644 --- a/doc.go +++ b/doc.go @@ -9,124 +9,124 @@ It provides a simple, yet powerful way to create solutions that incorporate mult Here is a "Classic Gobot" program that blinks an LED using an Arduino: - package main + package main - import ( - "time" + import ( + "time" - "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/drivers/gpio" - "gobot.io/x/gobot/v2/platforms/firmata" - ) + "gobot.io/x/gobot/v2" + "gobot.io/x/gobot/v2/drivers/gpio" + "gobot.io/x/gobot/v2/platforms/firmata" + ) - func main() { - firmataAdaptor := firmata.NewAdaptor("/dev/ttyACM0") - led := gpio.NewLedDriver(firmataAdaptor, "13") + func main() { + firmataAdaptor := firmata.NewAdaptor("/dev/ttyACM0") + led := gpio.NewLedDriver(firmataAdaptor, "13") - work := func() { - gobot.Every(1*time.Second, func() { - led.Toggle() - }) - } + work := func() { + gobot.Every(1*time.Second, func() { + led.Toggle() + }) + } - robot := gobot.NewRobot("bot", - []gobot.Connection{firmataAdaptor}, - []gobot.Device{led}, - work, - ) + robot := gobot.NewRobot("bot", + []gobot.Connection{firmataAdaptor}, + []gobot.Device{led}, + work, + ) - robot.Start() - } + robot.Start() + } # Metal Gobot You can also use Metal Gobot and pick and choose from the various Gobot packages to control hardware with nothing but pure idiomatic Golang code. For example: - package main + package main - import ( - "gobot.io/x/gobot/v2/drivers/gpio" - "gobot.io/x/gobot/v2/platforms/intel-iot/edison" - "time" - ) + import ( + "gobot.io/x/gobot/v2/drivers/gpio" + "gobot.io/x/gobot/v2/platforms/intel-iot/edison" + "time" + ) - func main() { - e := edison.NewAdaptor() - e.Connect() + func main() { + e := edison.NewAdaptor() + e.Connect() - led := gpio.NewLedDriver(e, "13") - led.Start() + led := gpio.NewLedDriver(e, "13") + led.Start() - for { - led.Toggle() - time.Sleep(1000 * time.Millisecond) - } - } + for { + led.Toggle() + time.Sleep(1000 * time.Millisecond) + } + } # Master Gobot Finally, you can use Master Gobot to add the complete Gobot API or control swarms of Robots: - package main - - import ( - "fmt" - "time" - - "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/api" - "gobot.io/x/gobot/v2/platforms/sphero" - ) - - func NewSwarmBot(port string) *gobot.Robot { - spheroAdaptor := sphero.NewAdaptor(port) - spheroDriver := sphero.NewSpheroDriver(spheroAdaptor) - spheroDriver.SetName("Sphero" + port) - - work := func() { - spheroDriver.Stop() - - spheroDriver.On(sphero.Collision, func(data interface{}) { - fmt.Println("Collision Detected!") - }) - - gobot.Every(1*time.Second, func() { - spheroDriver.Roll(100, uint16(gobot.Rand(360))) - }) - gobot.Every(3*time.Second, func() { - spheroDriver.SetRGB(uint8(gobot.Rand(255)), - uint8(gobot.Rand(255)), - uint8(gobot.Rand(255)), - ) - }) - } - - robot := gobot.NewRobot("sphero", - []gobot.Connection{spheroAdaptor}, - []gobot.Device{spheroDriver}, - work, - ) - - return robot - } - - func main() { - master := gobot.NewMaster() - api.NewAPI(master).Start() - - spheros := []string{ - "/dev/rfcomm0", - "/dev/rfcomm1", - "/dev/rfcomm2", - "/dev/rfcomm3", - } - - for _, port := range spheros { - master.AddRobot(NewSwarmBot(port)) - } - - master.Start() - } + package main + + import ( + "fmt" + "time" + + "gobot.io/x/gobot/v2" + "gobot.io/x/gobot/v2/api" + "gobot.io/x/gobot/v2/platforms/sphero" + ) + + func NewSwarmBot(port string) *gobot.Robot { + spheroAdaptor := sphero.NewAdaptor(port) + spheroDriver := sphero.NewSpheroDriver(spheroAdaptor) + spheroDriver.SetName("Sphero" + port) + + work := func() { + spheroDriver.Stop() + + spheroDriver.On(sphero.Collision, func(data interface{}) { + fmt.Println("Collision Detected!") + }) + + gobot.Every(1*time.Second, func() { + spheroDriver.Roll(100, uint16(gobot.Rand(360))) + }) + gobot.Every(3*time.Second, func() { + spheroDriver.SetRGB(uint8(gobot.Rand(255)), + uint8(gobot.Rand(255)), + uint8(gobot.Rand(255)), + ) + }) + } + + robot := gobot.NewRobot("sphero", + []gobot.Connection{spheroAdaptor}, + []gobot.Device{spheroDriver}, + work, + ) + + return robot + } + + func main() { + master := gobot.NewMaster() + api.NewAPI(master).Start() + + spheros := []string{ + "/dev/rfcomm0", + "/dev/rfcomm1", + "/dev/rfcomm2", + "/dev/rfcomm3", + } + + for _, port := range spheros { + master.AddRobot(NewSwarmBot(port)) + } + + master.Start() + } Copyright (c) 2013-2018 The Hybrid Group. Licensed under the Apache 2.0 license. */ diff --git a/drivers/aio/aio.go b/drivers/aio/aio.go index 4b8bd9638..a8d5b339a 100644 --- a/drivers/aio/aio.go +++ b/drivers/aio/aio.go @@ -4,11 +4,9 @@ import ( "errors" ) -var ( - // ErrAnalogReadUnsupported is error resulting when a driver attempts to use - // hardware capabilities which a connection does not support - ErrAnalogReadUnsupported = errors.New("AnalogRead is not supported by this platform") -) +// ErrAnalogReadUnsupported is error resulting when a driver attempts to use +// hardware capabilities which a connection does not support +var ErrAnalogReadUnsupported = errors.New("AnalogRead is not supported by this platform") const ( // Error event @@ -23,12 +21,12 @@ const ( // AnalogReader interface represents an Adaptor which has AnalogRead capabilities type AnalogReader interface { - //gobot.Adaptor + // gobot.Adaptor AnalogRead(pin string) (val int, err error) } // AnalogWriter interface represents an Adaptor which has AnalogWrite capabilities type AnalogWriter interface { - //gobot.Adaptor + // gobot.Adaptor AnalogWrite(pin string, val int) (err error) } diff --git a/drivers/aio/analog_actuator_driver_test.go b/drivers/aio/analog_actuator_driver_test.go index 67c296ea8..9124777b0 100644 --- a/drivers/aio/analog_actuator_driver_test.go +++ b/drivers/aio/analog_actuator_driver_test.go @@ -4,27 +4,27 @@ import ( "strings" "testing" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) func TestAnalogActuatorDriver(t *testing.T) { a := newAioTestAdaptor() d := NewAnalogActuatorDriver(a, "47") - gobottest.Refute(t, d.Connection(), nil) - gobottest.Assert(t, d.Pin(), "47") + assert.NotNil(t, d.Connection()) + assert.Equal(t, "47", d.Pin()) err := d.RawWrite(100) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], 100) + assert.NoError(t, err) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, 100, a.written[0]) err = d.Write(247.0) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 2) - gobottest.Assert(t, a.written[1], 247) - gobottest.Assert(t, d.RawValue(), 247) - gobottest.Assert(t, d.Value(), 247.0) + assert.NoError(t, err) + assert.Equal(t, 2, len(a.written)) + assert.Equal(t, 247, a.written[1]) + assert.Equal(t, 247, d.RawValue()) + assert.Equal(t, 247.0, d.Value()) } func TestAnalogActuatorDriverWithScaler(t *testing.T) { @@ -34,18 +34,18 @@ func TestAnalogActuatorDriverWithScaler(t *testing.T) { d.SetScaler(func(input float64) int { return int((input + 3) / 2.5) }) err := d.Command("RawWrite")(map[string]interface{}{"val": "100"}) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], 100) + assert.Nil(t, err) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, 100, a.written[0]) err = d.Command("Write")(map[string]interface{}{"val": "247.0"}) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 2) - gobottest.Assert(t, a.written[1], 100) + assert.Nil(t, err) + assert.Equal(t, 2, len(a.written)) + assert.Equal(t, 100, a.written[1]) } func TestAnalogActuatorDriverLinearScaler(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { fromMin float64 fromMax float64 input float64 @@ -76,30 +76,30 @@ func TestAnalogActuatorDriverLinearScaler(t *testing.T) { // act err := d.Write(tt.input) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], tt.want) + assert.NoError(t, err) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, tt.want, a.written[0]) }) } } func TestAnalogActuatorDriverStart(t *testing.T) { d := NewAnalogActuatorDriver(newAioTestAdaptor(), "1") - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestAnalogActuatorDriverHalt(t *testing.T) { d := NewAnalogActuatorDriver(newAioTestAdaptor(), "1") - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestAnalogActuatorDriverDefaultName(t *testing.T) { d := NewAnalogActuatorDriver(newAioTestAdaptor(), "1") - gobottest.Assert(t, strings.HasPrefix(d.Name(), "AnalogActuator"), true) + assert.True(t, strings.HasPrefix(d.Name(), "AnalogActuator")) } func TestAnalogActuatorDriverSetName(t *testing.T) { d := NewAnalogActuatorDriver(newAioTestAdaptor(), "1") d.SetName("mybot") - gobottest.Assert(t, d.Name(), "mybot") + assert.Equal(t, "mybot", d.Name()) } diff --git a/drivers/aio/analog_sensor_driver.go b/drivers/aio/analog_sensor_driver.go index fb8aaf2ab..450265955 100644 --- a/drivers/aio/analog_sensor_driver.go +++ b/drivers/aio/analog_sensor_driver.go @@ -77,8 +77,8 @@ func (a *AnalogSensorDriver) Start() (err error) { // cyclic reading deactivated return } - var oldRawValue = 0 - var oldValue = 0.0 + oldRawValue := 0 + oldValue := 0.0 go func() { timer := time.NewTimer(a.interval) timer.Stop() diff --git a/drivers/aio/analog_sensor_driver_test.go b/drivers/aio/analog_sensor_driver_test.go index 51371689c..3b60eb209 100644 --- a/drivers/aio/analog_sensor_driver_test.go +++ b/drivers/aio/analog_sensor_driver_test.go @@ -6,8 +6,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*AnalogSensorDriver)(nil) @@ -15,48 +15,49 @@ var _ gobot.Driver = (*AnalogSensorDriver)(nil) func TestAnalogSensorDriver(t *testing.T) { a := newAioTestAdaptor() d := NewAnalogSensorDriver(a, "1") - gobottest.Refute(t, d.Connection(), nil) + assert.NotNil(t, d.Connection()) // default interval - gobottest.Assert(t, d.interval, 10*time.Millisecond) + assert.Equal(t, 10*time.Millisecond, d.interval) // commands a = newAioTestAdaptor() d = NewAnalogSensorDriver(a, "42", 30*time.Second) d.SetScaler(func(input int) float64 { return 2.5*float64(input) - 3 }) - gobottest.Assert(t, d.Pin(), "42") - gobottest.Assert(t, d.interval, 30*time.Second) + assert.Equal(t, "42", d.Pin()) + assert.Equal(t, 30*time.Second, d.interval) - a.TestAdaptorAnalogRead(func() (val int, err error) { + a.analogReadFunc = func() (val int, err error) { val = 100 return - }) + } + ret := d.Command("ReadRaw")(nil).(map[string]interface{}) - gobottest.Assert(t, ret["val"].(int), 100) - gobottest.Assert(t, ret["err"], nil) + assert.Equal(t, 100, ret["val"].(int)) + assert.Nil(t, ret["err"]) ret = d.Command("Read")(nil).(map[string]interface{}) - gobottest.Assert(t, ret["val"].(float64), 247.0) - gobottest.Assert(t, ret["err"], nil) + assert.Equal(t, 247.0, ret["val"].(float64)) + assert.Nil(t, ret["err"]) // refresh value on read a = newAioTestAdaptor() d = NewAnalogSensorDriver(a, "3") - a.TestAdaptorAnalogRead(func() (val int, err error) { + a.analogReadFunc = func() (val int, err error) { val = 150 return - }) - gobottest.Assert(t, d.Value(), 0.0) + } + assert.Equal(t, 0.0, d.Value()) val, err := d.Read() - gobottest.Assert(t, err, nil) - gobottest.Assert(t, val, 150.0) - gobottest.Assert(t, d.Value(), 150.0) - gobottest.Assert(t, d.RawValue(), 150) + assert.NoError(t, err) + assert.Equal(t, 150.0, val) + assert.Equal(t, 150.0, d.Value()) + assert.Equal(t, 150, d.RawValue()) } func TestAnalogSensorDriverWithLinearScaler(t *testing.T) { // the input scales per default from 0...255 - var tests = map[string]struct { + tests := map[string]struct { toMin float64 toMax float64 input int @@ -78,14 +79,14 @@ func TestAnalogSensorDriverWithLinearScaler(t *testing.T) { t.Run(name, func(t *testing.T) { // arrange d.SetScaler(AnalogSensorLinearScaler(0, 255, tt.toMin, tt.toMax)) - a.TestAdaptorAnalogRead(func() (val int, err error) { + a.analogReadFunc = func() (val int, err error) { return tt.input, nil - }) + } // act got, err := d.Read() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, got, tt.want) + assert.NoError(t, err) + assert.Equal(t, tt.want, got) }) } } @@ -98,22 +99,22 @@ func TestAnalogSensorDriverStart(t *testing.T) { // expect data to be received _ = d.Once(d.Event(Data), func(data interface{}) { - gobottest.Assert(t, data.(int), 100) + assert.Equal(t, 100, data.(int)) sem <- true }) _ = d.Once(d.Event(Value), func(data interface{}) { - gobottest.Assert(t, data.(float64), 10000.0) + assert.Equal(t, 10000.0, data.(float64)) sem <- true }) // send data - a.TestAdaptorAnalogRead(func() (val int, err error) { + a.analogReadFunc = func() (val int, err error) { val = 100 return - }) + } - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) select { case <-sem: @@ -123,15 +124,15 @@ func TestAnalogSensorDriverStart(t *testing.T) { // expect error to be received _ = d.Once(d.Event(Error), func(data interface{}) { - gobottest.Assert(t, data.(error).Error(), "read error") + assert.Equal(t, "read error", data.(error).Error()) sem <- true }) // send error - a.TestAdaptorAnalogRead(func() (val int, err error) { + a.analogReadFunc = func() (val int, err error) { err = errors.New("read error") return - }) + } select { case <-sem: @@ -148,10 +149,10 @@ func TestAnalogSensorDriverStart(t *testing.T) { sem <- true }) - a.TestAdaptorAnalogRead(func() (val int, err error) { + a.analogReadFunc = func() (val int, err error) { val = 200 return - }) + } d.halt <- true @@ -169,7 +170,7 @@ func TestAnalogSensorDriverHalt(t *testing.T) { <-d.halt close(done) }() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) select { case <-done: case <-time.After(100 * time.Millisecond): @@ -179,11 +180,11 @@ func TestAnalogSensorDriverHalt(t *testing.T) { func TestAnalogSensorDriverDefaultName(t *testing.T) { d := NewAnalogSensorDriver(newAioTestAdaptor(), "1") - gobottest.Assert(t, strings.HasPrefix(d.Name(), "AnalogSensor"), true) + assert.True(t, strings.HasPrefix(d.Name(), "AnalogSensor")) } func TestAnalogSensorDriverSetName(t *testing.T) { d := NewAnalogSensorDriver(newAioTestAdaptor(), "1") d.SetName("mybot") - gobottest.Assert(t, d.Name(), "mybot") + assert.Equal(t, "mybot", d.Name()) } diff --git a/drivers/aio/grove_drivers_test.go b/drivers/aio/grove_drivers_test.go index a5395a3ed..e9ea6d408 100644 --- a/drivers/aio/grove_drivers_test.go +++ b/drivers/aio/grove_drivers_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) type DriverAndPinner interface { @@ -33,8 +33,8 @@ func TestDriverDefaults(t *testing.T) { } for _, driver := range drivers { - gobottest.Assert(t, driver.Connection(), testAdaptor) - gobottest.Assert(t, driver.Pin(), pin) + assert.Equal(t, testAdaptor, driver.Connection()) + assert.Equal(t, pin, driver.Pin()) } } @@ -51,10 +51,10 @@ func TestAnalogDriverHalt(t *testing.T) { for _, driver := range drivers { var callCount int32 - testAdaptor.TestAdaptorAnalogRead(func() (int, error) { + testAdaptor.analogReadFunc = func() (int, error) { atomic.AddInt32(&callCount, 1) return 42, nil - }) + } // Start the driver and allow for multiple digital reads _ = driver.Start() @@ -84,17 +84,16 @@ func TestDriverPublishesError(t *testing.T) { for _, driver := range drivers { sem := make(chan struct{}, 1) // send error - returnErr := func() (val int, err error) { + testAdaptor.analogReadFunc = func() (val int, err error) { err = errors.New("read error") return } - testAdaptor.TestAdaptorAnalogRead(returnErr) - gobottest.Assert(t, driver.Start(), nil) + assert.NoError(t, driver.Start()) // expect error _ = driver.Once(driver.Event(Error), func(data interface{}) { - gobottest.Assert(t, data.(error).Error(), "read error") + assert.Equal(t, "read error", data.(error).Error()) close(sem) }) diff --git a/drivers/aio/grove_temperature_sensor_driver.go b/drivers/aio/grove_temperature_sensor_driver.go index 2998b9811..78304a110 100644 --- a/drivers/aio/grove_temperature_sensor_driver.go +++ b/drivers/aio/grove_temperature_sensor_driver.go @@ -27,8 +27,8 @@ type GroveTemperatureSensorDriver struct { // "ReadValue" - See AnalogDriverSensor.ReadValue func NewGroveTemperatureSensorDriver(a AnalogReader, pin string, v ...time.Duration) *GroveTemperatureSensorDriver { t := NewTemperatureSensorDriver(a, pin, v...) - ntc := TemperatureSensorNtcConf{TC0: 25, R0: 10000.0, B: 3975} //Ohm, R25=10k - t.SetNtcScaler(1023, 10000, false, ntc) //Ohm, reference value: 1023, series R: 10k + ntc := TemperatureSensorNtcConf{TC0: 25, R0: 10000.0, B: 3975} // Ohm, R25=10k + t.SetNtcScaler(1023, 10000, false, ntc) // Ohm, reference value: 1023, series R: 10k d := &GroveTemperatureSensorDriver{ TemperatureSensorDriver: t, diff --git a/drivers/aio/grove_temperature_sensor_driver_test.go b/drivers/aio/grove_temperature_sensor_driver_test.go index d47f0fec1..602ad26c9 100644 --- a/drivers/aio/grove_temperature_sensor_driver_test.go +++ b/drivers/aio/grove_temperature_sensor_driver_test.go @@ -6,8 +6,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*GroveTemperatureSensorDriver)(nil) @@ -15,13 +15,13 @@ var _ gobot.Driver = (*GroveTemperatureSensorDriver)(nil) func TestGroveTemperatureSensorDriver(t *testing.T) { testAdaptor := newAioTestAdaptor() d := NewGroveTemperatureSensorDriver(testAdaptor, "123") - gobottest.Assert(t, d.Connection(), testAdaptor) - gobottest.Assert(t, d.Pin(), "123") - gobottest.Assert(t, d.interval, 10*time.Millisecond) + assert.Equal(t, testAdaptor, d.Connection()) + assert.Equal(t, "123", d.Pin()) + assert.Equal(t, 10*time.Millisecond, d.interval) } func TestGroveTemperatureSensorDriverScaling(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { input int want float64 }{ @@ -40,15 +40,15 @@ func TestGroveTemperatureSensorDriverScaling(t *testing.T) { for name, tt := range tests { t.Run(name, func(t *testing.T) { // arrange - a.TestAdaptorAnalogRead(func() (val int, err error) { + a.analogReadFunc = func() (val int, err error) { val = tt.input return - }) + } // act got, err := d.Read() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, got, tt.want) + assert.NoError(t, err) + assert.Equal(t, tt.want, got) }) } } @@ -58,15 +58,15 @@ func TestGroveTempSensorPublishesTemperatureInCelsius(t *testing.T) { a := newAioTestAdaptor() d := NewGroveTemperatureSensorDriver(a, "1") - a.TestAdaptorAnalogRead(func() (val int, err error) { + a.analogReadFunc = func() (val int, err error) { val = 585 return - }) + } _ = d.Once(d.Event(Value), func(data interface{}) { - gobottest.Assert(t, fmt.Sprintf("%.2f", data.(float64)), "31.62") + assert.Equal(t, "31.62", fmt.Sprintf("%.2f", data.(float64))) sem <- true }) - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) select { case <-sem: @@ -74,10 +74,10 @@ func TestGroveTempSensorPublishesTemperatureInCelsius(t *testing.T) { t.Errorf("Grove Temperature Sensor Event \"Data\" was not published") } - gobottest.Assert(t, d.Temperature(), 31.61532462352477) + assert.Equal(t, 31.61532462352477, d.Temperature()) } func TestGroveTempDriverDefaultName(t *testing.T) { d := NewGroveTemperatureSensorDriver(newAioTestAdaptor(), "1") - gobottest.Assert(t, strings.HasPrefix(d.Name(), "GroveTemperatureSensor"), true) + assert.True(t, strings.HasPrefix(d.Name(), "GroveTemperatureSensor")) } diff --git a/drivers/aio/helpers_test.go b/drivers/aio/helpers_test.go index 70df8edba..38ab5c2db 100644 --- a/drivers/aio/helpers_test.go +++ b/drivers/aio/helpers_test.go @@ -3,37 +3,42 @@ package aio import "sync" type aioTestAdaptor struct { - name string - port string - mtx sync.Mutex - testAdaptorAnalogRead func() (val int, err error) - testAdaptorAnalogWrite func(val int) (err error) - written []int + name string + port string + mtx sync.Mutex + analogReadFunc func() (val int, err error) + analogWriteFunc func(val int) (err error) + written []int } -func (t *aioTestAdaptor) TestAdaptorAnalogRead(f func() (val int, err error)) { - t.mtx.Lock() - defer t.mtx.Unlock() - t.testAdaptorAnalogRead = f -} +func newAioTestAdaptor() *aioTestAdaptor { + t := aioTestAdaptor{ + name: "aio_test_adaptor", + port: "/dev/null", + analogReadFunc: func() (val int, err error) { + return 99, nil + }, + analogWriteFunc: func(val int) (err error) { + return nil + }, + } -func (t *aioTestAdaptor) TestAdaptorAnalogWrite(f func(val int) (err error)) { - t.mtx.Lock() - defer t.mtx.Unlock() - t.testAdaptorAnalogWrite = f + return &t } +// AnalogRead capabilities (interface AnalogReader) func (t *aioTestAdaptor) AnalogRead(pin string) (val int, err error) { t.mtx.Lock() defer t.mtx.Unlock() - return t.testAdaptorAnalogRead() + return t.analogReadFunc() } +// AnalogWrite capabilities (interface AnalogWriter) func (t *aioTestAdaptor) AnalogWrite(pin string, val int) (err error) { t.mtx.Lock() defer t.mtx.Unlock() t.written = append(t.written, val) - return t.testAdaptorAnalogWrite(val) + return t.analogWriteFunc(val) } func (t *aioTestAdaptor) Connect() (err error) { return } @@ -41,15 +46,3 @@ func (t *aioTestAdaptor) Finalize() (err error) { return } func (t *aioTestAdaptor) Name() string { return t.name } func (t *aioTestAdaptor) SetName(n string) { t.name = n } func (t *aioTestAdaptor) Port() string { return t.port } - -func newAioTestAdaptor() *aioTestAdaptor { - return &aioTestAdaptor{ - port: "/dev/null", - testAdaptorAnalogRead: func() (val int, err error) { - return 99, nil - }, - testAdaptorAnalogWrite: func(val int) (err error) { - return nil - }, - } -} diff --git a/drivers/aio/temperature_sensor_driver.go b/drivers/aio/temperature_sensor_driver.go index f410e5c31..55c5484c0 100644 --- a/drivers/aio/temperature_sensor_driver.go +++ b/drivers/aio/temperature_sensor_driver.go @@ -126,7 +126,7 @@ func (n *TemperatureSensorNtcConf) getTemp(rntc float64) float64 { func (n *TemperatureSensorNtcConf) initialize() { n.t0 = float64(n.TC0) + kelvinOffset if n.B <= 0 { - //B=[ln(R0)-ln(R1)]/(1/T0-1/T1) + // B=[ln(R0)-ln(R1)]/(1/T0-1/T1) T1 := float64(n.TC1) + kelvinOffset n.B = (1/n.t0 - 1/T1) n.B = (math.Log(n.R0) - math.Log(n.R1)) / n.B // 2000K...5000K diff --git a/drivers/aio/temperature_sensor_driver_test.go b/drivers/aio/temperature_sensor_driver_test.go index b6012b7d3..7519ec46d 100644 --- a/drivers/aio/temperature_sensor_driver_test.go +++ b/drivers/aio/temperature_sensor_driver_test.go @@ -7,19 +7,19 @@ import ( "testing" "time" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) func TestTemperatureSensorDriver(t *testing.T) { testAdaptor := newAioTestAdaptor() d := NewTemperatureSensorDriver(testAdaptor, "123") - gobottest.Assert(t, d.Connection(), testAdaptor) - gobottest.Assert(t, d.Pin(), "123") - gobottest.Assert(t, d.interval, 10*time.Millisecond) + assert.Equal(t, testAdaptor, d.Connection()) + assert.Equal(t, "123", d.Pin()) + assert.Equal(t, 10*time.Millisecond, d.interval) } func TestTemperatureSensorDriverNtcScaling(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { input int want float64 }{ @@ -36,26 +36,26 @@ func TestTemperatureSensorDriverNtcScaling(t *testing.T) { } a := newAioTestAdaptor() d := NewTemperatureSensorDriver(a, "4") - ntc1 := TemperatureSensorNtcConf{TC0: 25, R0: 10000.0, B: 3950} //Ohm, R25=10k, B=3950 - d.SetNtcScaler(255, 1000, true, ntc1) //Ohm, reference value: 3300, series R: 1k + ntc1 := TemperatureSensorNtcConf{TC0: 25, R0: 10000.0, B: 3950} // Ohm, R25=10k, B=3950 + d.SetNtcScaler(255, 1000, true, ntc1) // Ohm, reference value: 3300, series R: 1k for name, tt := range tests { t.Run(name, func(t *testing.T) { // arrange - a.TestAdaptorAnalogRead(func() (val int, err error) { + a.analogReadFunc = func() (val int, err error) { val = tt.input return - }) + } // act got, err := d.Read() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, got, tt.want) + assert.NoError(t, err) + assert.Equal(t, tt.want, got) }) } } func TestTemperatureSensorDriverLinearScaling(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { input int want float64 }{ @@ -76,15 +76,15 @@ func TestTemperatureSensorDriverLinearScaling(t *testing.T) { for name, tt := range tests { t.Run(name, func(t *testing.T) { // arrange - a.TestAdaptorAnalogRead(func() (val int, err error) { + a.analogReadFunc = func() (val int, err error) { val = tt.input return - }) + } // act got, err := d.Read() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, got, tt.want) + assert.NoError(t, err) + assert.Equal(t, tt.want, got) }) } } @@ -93,18 +93,18 @@ func TestTempSensorPublishesTemperatureInCelsius(t *testing.T) { sem := make(chan bool, 1) a := newAioTestAdaptor() d := NewTemperatureSensorDriver(a, "1") - ntc := TemperatureSensorNtcConf{TC0: 25, R0: 10000.0, B: 3975} //Ohm, R25=10k - d.SetNtcScaler(1023, 10000, false, ntc) //Ohm, reference value: 1023, series R: 10k + ntc := TemperatureSensorNtcConf{TC0: 25, R0: 10000.0, B: 3975} // Ohm, R25=10k + d.SetNtcScaler(1023, 10000, false, ntc) // Ohm, reference value: 1023, series R: 10k - a.TestAdaptorAnalogRead(func() (val int, err error) { + a.analogReadFunc = func() (val int, err error) { val = 585 return - }) + } _ = d.Once(d.Event(Value), func(data interface{}) { - gobottest.Assert(t, fmt.Sprintf("%.2f", data.(float64)), "31.62") + assert.Equal(t, "31.62", fmt.Sprintf("%.2f", data.(float64))) sem <- true }) - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) select { case <-sem: @@ -112,7 +112,7 @@ func TestTempSensorPublishesTemperatureInCelsius(t *testing.T) { t.Errorf(" Temperature Sensor Event \"Data\" was not published") } - gobottest.Assert(t, d.Value(), 31.61532462352477) + assert.Equal(t, 31.61532462352477, d.Value()) } func TestTempSensorPublishesError(t *testing.T) { @@ -121,16 +121,16 @@ func TestTempSensorPublishesError(t *testing.T) { d := NewTemperatureSensorDriver(a, "1") // send error - a.TestAdaptorAnalogRead(func() (val int, err error) { + a.analogReadFunc = func() (val int, err error) { err = errors.New("read error") return - }) + } - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) // expect error _ = d.Once(d.Event(Error), func(data interface{}) { - gobottest.Assert(t, data.(error).Error(), "read error") + assert.Equal(t, "read error", data.(error).Error()) sem <- true }) @@ -148,7 +148,7 @@ func TestTempSensorHalt(t *testing.T) { <-d.halt close(done) }() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) select { case <-done: case <-time.After(100 * time.Millisecond): @@ -158,17 +158,17 @@ func TestTempSensorHalt(t *testing.T) { func TestTempDriverDefaultName(t *testing.T) { d := NewTemperatureSensorDriver(newAioTestAdaptor(), "1") - gobottest.Assert(t, strings.HasPrefix(d.Name(), "TemperatureSensor"), true) + assert.True(t, strings.HasPrefix(d.Name(), "TemperatureSensor")) } func TestTempDriverSetName(t *testing.T) { d := NewTemperatureSensorDriver(newAioTestAdaptor(), "1") d.SetName("mybot") - gobottest.Assert(t, d.Name(), "mybot") + assert.Equal(t, "mybot", d.Name()) } func TestTempDriver_initialize(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { input TemperatureSensorNtcConf want TemperatureSensorNtcConf }{ @@ -208,7 +208,7 @@ func TestTempDriver_initialize(t *testing.T) { // act ntc.initialize() // assert - gobottest.Assert(t, ntc, tt.want) + assert.Equal(t, tt.want, ntc) }) } } diff --git a/drivers/common/mfrc522/mfrc522_pcd.go b/drivers/common/mfrc522/mfrc522_pcd.go index 34ace2574..a6cad3495 100644 --- a/drivers/common/mfrc522/mfrc522_pcd.go +++ b/drivers/common/mfrc522/mfrc522_pcd.go @@ -20,8 +20,10 @@ type busConnection interface { WriteByteData(reg byte, data byte) error } -var versions = map[uint8]string{0x12: "Counterfeit", 0x88: "FM17522", 0x89: "FM17522E", - 0x90: "MFRC522 0.0", 0x91: "MFRC522 1.0", 0x92: "MFRC522 2.0", 0xB2: "FM17522 1"} +var versions = map[uint8]string{ + 0x12: "Counterfeit", 0x88: "FM17522", 0x89: "FM17522E", + 0x90: "MFRC522 0.0", 0x91: "MFRC522 1.0", 0x92: "MFRC522 2.0", 0xB2: "FM17522 1", +} // MFRC522Common is the Gobot Driver for MFRC522 RFID. // datasheet: @@ -155,7 +157,8 @@ func (d *MFRC522Common) stopCrypto1() error { } func (d *MFRC522Common) communicateWithPICC(command uint8, sendData []byte, backData []byte, txLastBits uint8, - checkCRC bool) error { + checkCRC bool, +) error { irqEn := 0x00 waitIRq := uint8(0x00) switch command { diff --git a/drivers/common/mfrc522/mfrc522_pcd_register.go b/drivers/common/mfrc522/mfrc522_pcd_register.go index 416f6ff3e..042e145aa 100644 --- a/drivers/common/mfrc522/mfrc522_pcd_register.go +++ b/drivers/common/mfrc522/mfrc522_pcd_register.go @@ -12,8 +12,8 @@ const ( commandRegCalcCRC = 0x03 // activates the CRC coprocessor or performs a self-test commandRegTransmit = 0x04 // transmits data from the FIFO buffer // 0x05, 0x06 not used - //commandRegNoCmdChange = 0x07 // no command change, can be used to modify the Command register bits without - //commandRegReceive = 0x08 // activates the receiver circuits + // commandRegNoCmdChange = 0x07 // no command change, can be used to modify the Command register bits without + // commandRegReceive = 0x08 // activates the receiver circuits // 0x09..0x0B not used commandRegTransceive = 0x0C // transmits data from FIFO buffer to antenna and automatically activates the receiver after transmission // 0x0D reserved @@ -57,10 +57,10 @@ const ( comIrqRegErrIRq1anyBit = 0x02 // bit 1: error bit in the Error register is set, if 1 // Status1 register’s LoAlert bit is set in opposition to the LoAlert bit, the LoAlertIRq bit stores this event and // can only be reset as indicated by the Set1 bit in this register - //comIrqRegLoAlertIRqBit = 0x04 // bit 2: if 1, see above + // comIrqRegLoAlertIRqBit = 0x04 // bit 2: if 1, see above // the Status1 register’s HiAlert bit is set in opposition to the HiAlert bit, the HiAlertIRq bit stores this event // and can only be reset as indicated by the Set1 bit in this register - //comIrqRegHiAlertIRqBit = 0x08 // bit 3: if 1, see above + // comIrqRegHiAlertIRqBit = 0x08 // bit 3: if 1, see above // If a command terminates, for example, when the Command register changes its value from any command to Idle command. // If an unknown command is started, the Command register Command[3:0] value changes to the idle state and the // IdleIRq bit is set. The microcontroller starting the Idle command does not set the IdleIRq bit. @@ -71,28 +71,28 @@ const ( comIrqRegTxIRqBit = 0x40 // bit 6: set to 1, immediately after the last bit of the transmitted data was sent out // 1: indicates that the marked bits in the register are set // 0: indicates that the marked bits in the register are cleared - //comIrqRegSet1Bit = 0x80 // bit 7: see above + // comIrqRegSet1Bit = 0x80 // bit 7: see above ) const ( regDivIrq = 0x05 // diverse interrupt request bits // ------------ values -------------------- - //divIrqRegReset = 0x00 // see table 31 of data sheet - //divIrqRegReserved01 = 0x03 + // divIrqRegReset = 0x00 // see table 31 of data sheet + // divIrqRegReserved01 = 0x03 divIrqRegCRCIRqBit = 0x04 // bit 2: the CalcCRC command is active and all data is processed - //divIrqRegReservedBit3 = 0x08 + // divIrqRegReservedBit3 = 0x08 // this interrupt is set when either a rising or falling signal edge is detected - //divIrqRegMfinActIRqBit = 0x10 // bit 4: MFIN is active; see above - //divIrqRegReserved56 = 0x60 + // divIrqRegMfinActIRqBit = 0x10 // bit 4: MFIN is active; see above + // divIrqRegReserved56 = 0x60 // 1: indicates that the marked bits in the register are set // 0: indicates that the marked bits in the register are cleared - //divIrqRegSet2Bit = 0x80 // bit 7: see above + // divIrqRegSet2Bit = 0x80 // bit 7: see above ) const ( regError = 0x06 // error bits showing the error status of the last command executed // ------------ values -------------------- - //errorRegReset = 0x00 // see table 33 of data sheet + // errorRegReset = 0x00 // see table 33 of data sheet // set to logic 1 if the SOF is incorrect automatically cleared during receiver start-up phase bit is only valid for // 106 kBd; during the MFAuthent command, the ProtocolErr bit is set to logic 1 if the number of bytes received in one // data stream is incorrect @@ -105,10 +105,10 @@ const ( // cleared automatically at receiver start-up phase; only valid during the bitwise anticollision at 106 kBd; always // set to logic 0 during communication protocols at 212 kBd, 424 kBd and 848 kBd errorRegCollErrBit = 0x08 // bit 3: a bit-collision is detected, see above - //the host or a MFRC522’s internal state machine (e.g. receiver) tries to write data to the FIFO buffer even though + // the host or a MFRC522’s internal state machine (e.g. receiver) tries to write data to the FIFO buffer even though // it is already full errorRegBufferOvflBit = 0x10 // bit 4: FIFO is full, see above - //errorRegReservedBit5 = 0x20 + // errorRegReservedBit5 = 0x20 // the antenna drivers are automatically switched off errorRegTempErrBit = 0x40 // bit 6: internal temperature sensor detects overheating, see above // data is written into the FIFO buffer by the host during the MFAuthent command or if data is written into the FIFO @@ -125,25 +125,25 @@ const ( const ( regStatus2 = 0x08 // receiver and transmitter status bits // ------------ values -------------------- - //status2RegReset = 0x00 // see table 37 of data sheet + // status2RegReset = 0x00 // see table 37 of data sheet // bit 0..2 shows the state of the transmitter and receiver state machines - //status2RegModemStateIdle = 0x00 // idle - //status2RegModemStateWait = 0x01 // wait for the BitFraming register’s StartSend bit + // status2RegModemStateIdle = 0x00 // idle + // status2RegModemStateWait = 0x01 // wait for the BitFraming register’s StartSend bit // the minimum time for TxWait is defined by the TxWait register - //status2RegModemStateTxWait = 0x02 // wait until RF field is present if the TMode register’s TxWaitRF bit is set to logic 1 - //status2RegModemStateTransmitting = 0x03 + // status2RegModemStateTxWait = 0x02 // wait until RF field is present if the TMode register’s TxWaitRF bit is set to logic 1 + // status2RegModemStateTransmitting = 0x03 // the minimum time for RxWait is defined by the RxWait register - //status2RegModemStateRxWait = 0x04 // wait until RF field is present if the TMode register’s TxWaitRF bit is set to logic 1 - //status2RegModemStateWaitForData = 0x05 - //status2RegModemStateReceiving = 0x06 + // status2RegModemStateRxWait = 0x04 // wait until RF field is present if the TMode register’s TxWaitRF bit is set to logic 1 + // status2RegModemStateWaitForData = 0x05 + // status2RegModemStateReceiving = 0x06 // all data communication with the card is encrypted; can only be set to logic 1 by a successful execution of the // MFAuthent command; only valid in Read/Write mode for MIFARE standard cards; this bit is cleared by software status2RegMFCrypto1OnBit = 0x08 // bit 3: indicates that the MIFARE Crypto1 unit is switched on and, see above - //status2RegReserved45 = 0x30 + // status2RegReserved45 = 0x30 // 1: the I2C-bus input filter is set to the High-speed mode independent of the I2C-bus protocol // 0: the I2C-bus input filter is set to the I2C-bus protocol used - //status2RegI2cForceHSBit = 0x40 // I2C-bus input filter settings, see above - //status2RegTempSensClear1Bit = 0x80 // clears the temperature error if the temperature is below the alarm limit of 125C + // status2RegI2cForceHSBit = 0x40 // I2C-bus input filter settings, see above + // status2RegTempSensClear1Bit = 0x80 // clears the temperature error if the temperature is below the alarm limit of 125C ) const ( @@ -153,10 +153,10 @@ const ( const ( regFIFOLevel = 0x0A // number of bytes stored in the FIFO buffer // ------------ values -------------------- - //fifoLevelRegReset = 0x00 // see table 41 of data sheet + // fifoLevelRegReset = 0x00 // see table 41 of data sheet // indicates the number of bytes stored in the FIFO buffer writing to the FIFOData register increments and reading // decrements the FIFOLevel value - //fifoLevelRegValue = 0x7F // bit 0..6: see above + // fifoLevelRegValue = 0x7F // bit 0..6: see above // immediately clears the internal FIFO buffer’s read and write pointer and Error register’s BufferOvfl bit reading // this bit always returns 0 fifoLevelRegFlushBufferBit = 0x80 // bit 7: see above @@ -170,13 +170,13 @@ const ( const ( regControl = 0x0C // miscellaneous control registers // ------------ values -------------------- - //controlRegReset = 0x10 // see table 45 of data sheet + // controlRegReset = 0x10 // see table 45 of data sheet // indicates the number of valid bits in the last received byte // if this value is 000b, the whole byte is valid controlRegRxLastBits = 0x07 // bit 0..2: see above - //controlRegReserved3to5 = 0x38 - //controlRegTStartNowBit = 0x40 // bit 6: timer starts immediately, if 1; reading always returns logic 0 - //controlRegTStopNow = 0x80 // bit 7: timer stops immediately, if 1; reading always returns logic 0 + // controlRegReserved3to5 = 0x38 + // controlRegTStartNowBit = 0x40 // bit 6: timer starts immediately, if 1; reading always returns logic 0 + // controlRegTStopNow = 0x80 // bit 7: timer stops immediately, if 1; reading always returns logic 0 ) const ( @@ -186,7 +186,7 @@ const ( // used for transmission of bit oriented frames: defines the number of bits of the last byte that will be transmitted // 000b indicates that all bits of the last byte will be transmitted bitFramingRegTxLastBits = 0x07 // bit 0..2: see above - //bitFramingRegReservedBit3 = 0x08 + // bitFramingRegReservedBit3 = 0x08 // used for reception of bit-oriented frames: defines the bit position for the first bit received to be stored in the // FIFO buffer, example: // 0: LSB of the received bit is stored at bit position 0, the second received bit is stored at bit position 1 @@ -194,8 +194,8 @@ const ( // 7: LSB of the received bit is stored at bit position 7, the second received bit is stored in the next byte that // follows at bit position 0 // These bits are only to be used for bitwise anticollision at 106 kBd, for all other modes they are set to 0 - //bitFramingRegRxAlign = 0x70 // bit 4..6: see above - //starts the transmission of data, only valid in combination with the Transceive command + // bitFramingRegRxAlign = 0x70 // bit 4..6: see above + // starts the transmission of data, only valid in combination with the Transceive command bitFramingRegStartSendBit = 0x80 // bit 7: see above ) @@ -207,10 +207,10 @@ const ( // 01: indicates a bit-collision in the 1st bit // 08: indicates a bit-collision in the 8th bit // These bits will only be interpreted if the CollPosNotValid bit is set to logic 0 - //collRegCollPos = 0x1F // bit 0..4: read-only, see above + // collRegCollPos = 0x1F // bit 0..4: read-only, see above // no collision detected or the position of the collision is out of the range of CollPos[4:0], if set to 1 - //collRegCollPosNotValidBit = 0x20 // bit 5: read-only, see above - //collRegReservedBit6 = 0x40 + // collRegCollPosNotValidBit = 0x20 // bit 5: read-only, see above + // collRegReservedBit6 = 0x40 // all received bits will be cleared after a collision only used during bitwise anticollision at 106 kBd, otherwise it // is set to logic 1 collRegValuesAfterCollBit = 0x80 // bit 7: see above @@ -223,7 +223,7 @@ const ( const ( regMode = 0x11 // defines general modes for transmitting and receiving // ------------ values -------------------- - //modeRegReset = 0x3F // see table 55 of data sheet + // modeRegReset = 0x3F // see table 55 of data sheet // bit 0..1: defines the preset value for the CRC coprocessor for the CalcCRC command; Remark: during any // communication, the preset values are selected automatically according to the definition of bits in the rxModeReg // and TxMode registers @@ -231,16 +231,16 @@ const ( modeRegCRCPreset6363 = 0x01 // 0x6363 modeRegCRCPresetA671 = 0x10 // 0xA671 modeRegCRCPresetFFFF = 0x11 // 0xFFFF - //modeRegReservedBit2 = 0x04 + // modeRegReservedBit2 = 0x04 // defines the polarity of pin MFIN; Remark: the internal envelope signal is encoded active LOW, changing this bit // generates a MFinActIRq event modeRegPolMFinBit = 0x08 // bit 3: polarity of pin MFIN is active HIGH, is set to 1 - //modeRegReservedBit4 = 0x10 + // modeRegReservedBit4 = 0x10 modeRegTxWaitRFBit = 0x20 // bit 5: transmitter can only be started if an RF field is generated, if set to 1 - //modeRegReservedBit6 = 0x40 + // modeRegReservedBit6 = 0x40 // CRC coprocessor calculates the CRC with MSB first 0 in the CRCResult register the values for the CRCResultMSB[7:0] // bits and the CRCResultLSB[7:0] bits are bit reversed; Remark: during RF communication this bit is ignored - //modeRegMSBFirstBit = 0x80 // bit 7: see above, if set to 1 + // modeRegMSBFirstBit = 0x80 // bit 7: see above, if set to 1 ) const ( @@ -248,8 +248,8 @@ const ( regRxMode = 0x13 // defines reception data rate and framing // ------------ values -------------------- rxtxModeRegReset = 0x00 - //txModeRegReserved = 0x07 // bit 0..2 reserved for TX - //rxModeRegReserved = 0x03 // bit 0,1 reserved for RX + // txModeRegReserved = 0x07 // bit 0..2 reserved for TX + // rxModeRegReserved = 0x03 // bit 0,1 reserved for RX // 0: receiver is deactivated after receiving a data frame // 1: able to receive more than one data frame; only valid for data rates above 106 kBd in order to handle the // polling command; after setting this bit the Receive and Transceive commands will not terminate automatically. @@ -260,60 +260,60 @@ const ( // version 1.0 the CRC status is reflected in the signal CRCErr. // rxModeRegRxMultipleBit = 0x04 // an invalid received data stream (less than 4 bits received) will be ignored and the receiver remains active -//rxModeRegRxNoErrBit = 0x08 // bit 3 -//txModeRegInvModBit = 0x08 // bit 3: modulation of transmitted data is inverted, if 1 +// rxModeRegRxNoErrBit = 0x08 // bit 3 +// txModeRegInvModBit = 0x08 // bit 3: modulation of transmitted data is inverted, if 1 // bit 4..6: defines the bit rate during data transmission; the handles transfer speeds up to 848 kBd -//rxtxModeRegSpeed106kBd = 0x00 //106 kBd -//rxtxModeRegSpeed212kBd = 0x10 //212 kBd -//rxtxModeRegSpeed424kBd = 0x20 //424 kBd -//rxtxModeRegSpeed848kBd = 0x30 //848 kBd -//rxtxModeRegSpeedRes1 = 0x40 //reserved -//rxtxModeRegSpeedRes2 = 0x50 //reserved -//rxtxModeRegSpeedRes3 = 0x60 //reserved -//rxtxModeRegSpeedRes4 = 0x70 //reserved +// rxtxModeRegSpeed106kBd = 0x00 //106 kBd +// rxtxModeRegSpeed212kBd = 0x10 //212 kBd +// rxtxModeRegSpeed424kBd = 0x20 //424 kBd +// rxtxModeRegSpeed848kBd = 0x30 //848 kBd +// rxtxModeRegSpeedRes1 = 0x40 //reserved +// rxtxModeRegSpeedRes2 = 0x50 //reserved +// rxtxModeRegSpeedRes3 = 0x60 //reserved +// rxtxModeRegSpeedRes4 = 0x70 //reserved // RX: enables the CRC calculation during reception // TX: enables CRC generation during data transmission -//rxtxModeRegTxCRCEnBit = 0x80 // bit 7: can only be set to logic 0 at 106 kBd +// rxtxModeRegTxCRCEnBit = 0x80 // bit 7: can only be set to logic 0 at 106 kBd ) const ( regTxControl = 0x14 // controls the logical behavior of the antenna driver pins TX1 and TX2 // ------------ values -------------------- - //regtxControlRegReset = 0x80 // see table 61 of data sheet + // regtxControlRegReset = 0x80 // see table 61 of data sheet // signal on pin TX1 delivers the 13.56 MHz energy carrier modulated by the transmission data txControlRegTx1RFEn1outputBit = 0x01 // bit 0: see above // signal on pin TX2 delivers the 13.56 MHz energy carrier modulated by the transmission data txControlRegTx2RFEn1outputBit = 0x02 // bit 1: see above - //txControlRegReservedBit2 = 0x04 + // txControlRegReservedBit2 = 0x04 // signal on pin TX2 continuously delivers the unmodulated 13.56 MHz energy carrier0Tx2CW bit is enabled to modulate // the 13.56 MHz energy carrier - //txControlRegTx2CW1outputBit = 0x08 // bit 3: see above - //txControlRegInvTx1RFOffBit = 0x10 // bit 4: output signal on pin TX1 inverted if driver TX1 is disabled, if 1 - //txControlRegInvTx2RFOffBit = 0x20 // bit 5: output signal on pin TX2 inverted if driver TX2 is disabled, if 1 - //txControlRegInvTx1RFOnBit = 0x40 // bit 6: output signal on pin TX1 inverted if driver TX1 is enabled, if 1 - //txControlRegInvTx2RFOnBit = 0x80 // bit 7: output signal on pin TX2 inverted if driver TX2 is enabled, if 1 + // txControlRegTx2CW1outputBit = 0x08 // bit 3: see above + // txControlRegInvTx1RFOffBit = 0x10 // bit 4: output signal on pin TX1 inverted if driver TX1 is disabled, if 1 + // txControlRegInvTx2RFOffBit = 0x20 // bit 5: output signal on pin TX2 inverted if driver TX2 is disabled, if 1 + // txControlRegInvTx1RFOnBit = 0x40 // bit 6: output signal on pin TX1 inverted if driver TX1 is enabled, if 1 + // txControlRegInvTx2RFOnBit = 0x80 // bit 7: output signal on pin TX2 inverted if driver TX2 is enabled, if 1 ) const ( regTxASK = 0x15 // controls the setting of the transmission modulation // ------------ values -------------------- - //txASKRegReset = 0x00 // see table 63 of data sheet - //txASKRegReserved = 0x3F // bit 0..5 + // txASKRegReset = 0x00 // see table 63 of data sheet + // txASKRegReserved = 0x3F // bit 0..5 txASKRegForce100ASKBit = 0x40 // bit 6: forces a 100 % ASK modulation independent of the ModGsP register - //txASKRegReservedBit7 = 0x80 + // txASKRegReservedBit7 = 0x80 ) const ( - //regTxSel = 0x16 // selects the internal sources for the antenna driver - //regRxSel = 0x17 // selects internal receiver settings - //regRxThreshold = 0x18 // selects thresholds for the bit decoder - //regDemod = 0x19 // defines demodulator settings + // regTxSel = 0x16 // selects the internal sources for the antenna driver + // regRxSel = 0x17 // selects internal receiver settings + // regRxThreshold = 0x18 // selects thresholds for the bit decoder + // regDemod = 0x19 // defines demodulator settings // 0x1A // reserved for future use // 0x1B // reserved for future use - //regMfTx = 0x1C // controls some MIFARE communication transmit parameters - //regMfRx = 0x1D // controls some MIFARE communication receive parameters + // regMfTx = 0x1C // controls some MIFARE communication transmit parameters + // regMfRx = 0x1D // controls some MIFARE communication receive parameters // 0x1E // reserved for future use - //regSerialSpeed = 0x1F // selects the speed of the serial UART interface + // regSerialSpeed = 0x1F // selects the speed of the serial UART interface // Page 2: Configuration // 0x20 // reserved for future use @@ -333,8 +333,8 @@ const ( const ( regRFCfg = 0x26 // configures the receiver gain // ------------ values -------------------- - //rfcCfgRegReset = 0x48 // see table 97 of data sheet - //rfcCfgRegReserved03 = 0x07 + // rfcCfgRegReset = 0x48 // see table 97 of data sheet + // rfcCfgRegReserved03 = 0x07 // bit 4..6: defines the receiver’s signal voltage gain factor rfcCfgRegRxGain18dB = 0x00 rfcCfgRegRxGain23dB = 0x10 @@ -344,22 +344,22 @@ const ( rfcCfgRegRxGain38dB = 0x50 rfcCfgRegRxGain43dB = 0x60 rfcCfgRegRxGain48dB = 0x70 - //rfcCfgRegReserved7 = 0x80 + // rfcCfgRegReserved7 = 0x80 ) const ( // ------------ unused commands -------------------- -//regGsN = 0x27 // selects the conductance of the antenna driver pins TX1 and TX2 for modulation -//regCWGsP = 0x28 // defines the conductance of the p-driver output during periods of no modulation -//regModGsP = 0x29 // defines the conductance of the p-driver output during periods of modulation - +// regGsN = 0x27 // selects the conductance of the antenna driver pins TX1 and TX2 for modulation +// regCWGsP = 0x28 // defines the conductance of the p-driver output during periods of no modulation +// regModGsP = 0x29 // defines the conductance of the p-driver output during periods of modulation ) + const ( regTMode = 0x2A // defines settings for the internal timer regTPrescaler = 0x2B // the lower 8 bits of the TPrescaler value. The 4 high bits are in tModeReg. // ------------ values -------------------- - //tModeRegReset = 0x00 // see table 105 of data sheet - //tPrescalerRegReset = 0x00 // see table 107 of data sheet + // tModeRegReset = 0x00 // see table 105 of data sheet + // tPrescalerRegReset = 0x00 // see table 107 of data sheet // timer starts automatically at the end of the transmission in all communication modes at all speeds; if the // RxMode register’s RxMultiple bit is not set, the timer stops immediately after receiving the 5th bit (1 start // bit, 4 data bits); if the RxMultiple bit is set to logic 1 the timer never stops, in which case the timer can be @@ -368,22 +368,22 @@ const ( // bit 6,5: indicates that the timer is not influenced by the protocol; internal timer is running in // gated mode; Remark: in gated mode, the Status1 register’s TRunning bit is logic 1 when the timer is enabled by // the TMode register’s TGated bits; this bit does not influence the gating signal - //tModeRegTGatedNon = 0x00 // non-gated mode - //tModeRegTGatedMFIN = 0x20 // gated by pin MFIN - //tModeRegTGatedAUX1 = 0x40 // gated by pin AUX1 + // tModeRegTGatedNon = 0x00 // non-gated mode + // tModeRegTGatedMFIN = 0x20 // gated by pin MFIN + // tModeRegTGatedAUX1 = 0x40 // gated by pin AUX1 // 1: timer automatically restarts its count-down from the 16-bit timer reload value instead of counting down to zero // 0: timer decrements to 0 and the ComIrq register’s TimerIRq bit is set to logic 1 - //tModeRegTAutoRestartBit = 0x10 // bit 4, see above + // tModeRegTAutoRestartBit = 0x10 // bit 4, see above // defines the higher 4 bits of the TPrescaler value; The following formula is used to calculate the timer // frequency if the Demod register’s TPrescalEven bit in Demot register’s set to logic 0: // ftimer = 13.56 MHz / (2*TPreScaler+1); TPreScaler = [tPrescalerRegHi:tPrescalerRegLo] // TPrescaler value on 12 bits) (Default TPrescalEven bit is logic 0) // The following formula is used to calculate the timer frequency if the Demod register’s TPrescalEven bit is set // to logic 1: ftimer = 13.56 MHz / (2*TPreScaler+2). - //tModeRegtPrescalerRegValue25us = 0x0A9 // 169 => fRegtimer=40kHz, timer period of 25μs. - //tModeRegtPrescalerRegValue38us = 0x0FF // 255 => fRegtimer=26kHz, timer period of 38μs. - //tModeRegtPrescalerRegValue500us = 0xD3E // 3390 => fRegtimer= 2kHz, timer period of 500us. - //tModeRegtPrescalerRegValue604us = 0xFFF // 4095 => fRegtimer=1.65kHz, timer period of 604us. + // tModeRegtPrescalerRegValue25us = 0x0A9 // 169 => fRegtimer=40kHz, timer period of 25μs. + // tModeRegtPrescalerRegValue38us = 0x0FF // 255 => fRegtimer=26kHz, timer period of 38μs. + // tModeRegtPrescalerRegValue500us = 0xD3E // 3390 => fRegtimer= 2kHz, timer period of 500us. + // tModeRegtPrescalerRegValue604us = 0xFFF // 4095 => fRegtimer=1.65kHz, timer period of 604us. ) const ( @@ -399,8 +399,8 @@ const ( const ( // ------------ unused commands -------------------- - //regTCounterValueH = 0x2E // shows the 16-bit timer value - //regTCounterValueL = 0x2F + // regTCounterValueH = 0x2E // shows the 16-bit timer value + // regTCounterValueL = 0x2F // Page 3: Test Registers // 0x30 // reserved for future use diff --git a/drivers/common/mfrc522/mfrc522_pcd_test.go b/drivers/common/mfrc522/mfrc522_pcd_test.go index b640fe2a2..891d60ea6 100644 --- a/drivers/common/mfrc522/mfrc522_pcd_test.go +++ b/drivers/common/mfrc522/mfrc522_pcd_test.go @@ -3,7 +3,7 @@ package mfrc522 import ( "testing" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) type busConnMock struct { @@ -49,7 +49,7 @@ func TestNewMFRC522Common(t *testing.T) { // act d := NewMFRC522Common() // assert - gobottest.Refute(t, d, nil) + assert.NotNil(t, d) } func TestInitialize(t *testing.T) { @@ -63,12 +63,12 @@ func TestInitialize(t *testing.T) { // act err := d.Initialize(c) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, d.connection, c) - gobottest.Assert(t, c.written[:3], wantSoftReset) - gobottest.Assert(t, c.written[3:21], wantInit) - gobottest.Assert(t, c.written[21:24], wantAntennaOn) - gobottest.Assert(t, c.written[24:], wantGain) + assert.NoError(t, err) + assert.Equal(t, c, d.connection) + assert.Equal(t, wantSoftReset, c.written[:3]) + assert.Equal(t, wantInit, c.written[3:21]) + assert.Equal(t, wantAntennaOn, c.written[21:24]) + assert.Equal(t, wantGain, c.written[24:]) } func Test_getVersion(t *testing.T) { @@ -80,13 +80,13 @@ func Test_getVersion(t *testing.T) { // act got, err := d.getVersion() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, got, want) - gobottest.Assert(t, c.written, wantWritten) + assert.NoError(t, err) + assert.Equal(t, want, got) + assert.Equal(t, wantWritten, c.written) } func Test_switchAntenna(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { target bool simRead byte wantWritten []byte @@ -120,8 +120,8 @@ func Test_switchAntenna(t *testing.T) { // act err := d.switchAntenna(tc.target) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, c.written, tc.wantWritten) + assert.NoError(t, err) + assert.Equal(t, tc.wantWritten, c.written) }) } } @@ -134,8 +134,8 @@ func Test_stopCrypto1(t *testing.T) { // act err := d.stopCrypto1() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, c.written, wantWritten) + assert.NoError(t, err) + assert.Equal(t, wantWritten, c.written) } func Test_communicateWithPICC(t *testing.T) { @@ -158,14 +158,14 @@ func Test_communicateWithPICC(t *testing.T) { // transceive, all 8 bits, no CRC err := d.communicateWithPICC(0x0C, dataToFifo, backData, 0x00, false) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, c.written[:8], writtenPrepare) - gobottest.Assert(t, c.written[8:12], writtenWriteFifo) - gobottest.Assert(t, c.written[12:16], writtenTransceive) - gobottest.Assert(t, c.written[16:19], writtenBitFramingStart) - gobottest.Assert(t, c.written[19:24], writtenWaitAndFinish) - gobottest.Assert(t, c.written[24:], writtenReadFifo) - gobottest.Assert(t, backData, []byte{0x11, 0x22}) + assert.NoError(t, err) + assert.Equal(t, writtenPrepare, c.written[:8]) + assert.Equal(t, writtenWriteFifo, c.written[8:12]) + assert.Equal(t, writtenTransceive, c.written[12:16]) + assert.Equal(t, writtenBitFramingStart, c.written[16:19]) + assert.Equal(t, writtenWaitAndFinish, c.written[19:24]) + assert.Equal(t, writtenReadFifo, c.written[24:]) + assert.Equal(t, []byte{0x11, 0x22}, backData) } func Test_calculateCRC(t *testing.T) { @@ -181,12 +181,12 @@ func Test_calculateCRC(t *testing.T) { // act err := d.calculateCRC(dataToFifo, gotCrcBack) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, c.written[:6], writtenPrepare) - gobottest.Assert(t, c.written[6:10], writtenFifo) - gobottest.Assert(t, c.written[10:15], writtenCalc) - gobottest.Assert(t, c.written[15:], writtenGetResult) - gobottest.Assert(t, gotCrcBack, []byte{0x11, 0x22}) + assert.NoError(t, err) + assert.Equal(t, writtenPrepare, c.written[:6]) + assert.Equal(t, writtenFifo, c.written[6:10]) + assert.Equal(t, writtenCalc, c.written[10:15]) + assert.Equal(t, writtenGetResult, c.written[15:]) + assert.Equal(t, []byte{0x11, 0x22}, gotCrcBack) } func Test_writeFifo(t *testing.T) { @@ -197,8 +197,8 @@ func Test_writeFifo(t *testing.T) { // act err := d.writeFifo(dataToFifo) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, c.written, wantWritten) + assert.NoError(t, err) + assert.Equal(t, wantWritten, c.written) } func Test_readFifo(t *testing.T) { @@ -210,7 +210,7 @@ func Test_readFifo(t *testing.T) { // act _, err := d.readFifo(backData) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, c.written, wantWritten) - gobottest.Assert(t, backData, c.simFifo) + assert.NoError(t, err) + assert.Equal(t, wantWritten, c.written) + assert.Equal(t, c.simFifo, backData) } diff --git a/drivers/common/mfrc522/mfrc522_picc.go b/drivers/common/mfrc522/mfrc522_picc.go index 3723181dc..32d2bae2f 100644 --- a/drivers/common/mfrc522/mfrc522_picc.go +++ b/drivers/common/mfrc522/mfrc522_picc.go @@ -36,16 +36,20 @@ const ( piccCommandMFRegTRANSFER = 0xB0 // Writes the contents of the internal data register to a block. // The commands used for MIFARE Ultralight (from http://www.nxp.com/documents/dataRegsheet/MF0ICU1.pdf, Section 8.6) // The piccCommandMFRegREAD and piccCommandMFRegWRITE can also be used for MIFARE Ultralight. - //piccCommandULRegWRITE = 0xA2 // Writes one 4 byte page to the PICC. + // piccCommandULRegWRITE = 0xA2 // Writes one 4 byte page to the PICC. ) const piccReadWriteAuthBlock = uint8(11) -var piccKey = []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} -var piccUserBlockAddresses = []byte{8, 9, 10} +var ( + piccKey = []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} + piccUserBlockAddresses = []byte{8, 9, 10} +) -var piccCardFromSak = map[uint8]string{0x08: "Classic 1K, Plus 2K-SE-1K(SL1)", 0x18: "Classic 4K, Plus 4K(SL1)", - 0x10: "Plus 2K(SL2)", 0x11: "Plus 4K(SL2)", 0x20: "Plus 2K-SE-1K(SL3), Plus 4K(SL3)"} +var piccCardFromSak = map[uint8]string{ + 0x08: "Classic 1K, Plus 2K-SE-1K(SL1)", 0x18: "Classic 4K, Plus 4K(SL1)", + 0x10: "Plus 2K(SL2)", 0x11: "Plus 4K(SL2)", 0x20: "Plus 2K-SE-1K(SL3), Plus 4K(SL3)", +} // IsCardPresent is used to poll for a card in range. After an successful request, the card is halted. func (d *MFRC522Common) IsCardPresent() error { diff --git a/drivers/gpio/README.md b/drivers/gpio/README.md index e9b2da3aa..fbd8fe192 100644 --- a/drivers/gpio/README.md +++ b/drivers/gpio/README.md @@ -12,17 +12,22 @@ Please refer to the main [README.md](https://github.com/hybridgroup/gobot/blob/r Gobot has a extensible system for connecting to hardware devices. The following GPIO devices are currently supported: +- AIP1640 LED Dot Matrix/7 Segment Controller - Button - Buzzer - Direct Pin +- EasyDriver - Grove Button - Grove Buzzer - Grove LED - Grove Magnetic Switch - Grove Relay - Grove Touch Sensor +- HC-SR04 Ultrasonic Ranging Module +- HD44780 LCD controller - LED - Makey Button +- MAX7219 LED Dot Matrix - Motor - Proximity Infra Red (PIR) Motion Sensor - Relay @@ -30,5 +35,3 @@ Gobot has a extensible system for connecting to hardware devices. The following - Servo - Stepper Motor - TM1638 LED Controller - -More drivers are coming soon... diff --git a/drivers/gpio/aip1640_driver_test.go b/drivers/gpio/aip1640_driver_test.go index 796ba8b46..d7d8e256b 100644 --- a/drivers/gpio/aip1640_driver_test.go +++ b/drivers/gpio/aip1640_driver_test.go @@ -4,8 +4,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*AIP1640Driver)(nil) @@ -32,62 +32,62 @@ func TestAIP1640Driver(t *testing.T) { func TestAIP1640DriverStart(t *testing.T) { d := initTestAIP1640Driver() - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestAIP1640DriverHalt(t *testing.T) { d := initTestAIP1640Driver() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestAIP1640DriverDefaultName(t *testing.T) { d := initTestAIP1640Driver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "AIP1640Driver"), true) + assert.True(t, strings.HasPrefix(d.Name(), "AIP1640Driver")) } func TestAIP1640DriverSetName(t *testing.T) { d := initTestAIP1640Driver() d.SetName("mybot") - gobottest.Assert(t, d.Name(), "mybot") + assert.Equal(t, "mybot", d.Name()) } func TestAIP1640DriveDrawPixel(t *testing.T) { d := initTestAIP1640Driver() d.DrawPixel(2, 3, true) d.DrawPixel(0, 3, true) - gobottest.Assert(t, uint8(5), d.buffer[7-3]) + assert.Equal(t, d.buffer[7-3], uint8(5)) } func TestAIP1640DriverDrawRow(t *testing.T) { d := initTestAIP1640Driver() d.DrawRow(4, 0x3C) - gobottest.Assert(t, uint8(0x3C), d.buffer[7-4]) + assert.Equal(t, d.buffer[7-4], uint8(0x3C)) } func TestAIP1640DriverDrawMatrix(t *testing.T) { d := initTestAIP1640Driver() drawing := [8]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF} d.DrawMatrix(drawing) - gobottest.Assert(t, [8]byte{0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01}, d.buffer) + assert.Equal(t, d.buffer, [8]byte{0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01}) } func TestAIP1640DriverClear(t *testing.T) { d := initTestAIP1640Driver() drawing := [8]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF} d.DrawMatrix(drawing) - gobottest.Assert(t, [8]byte{0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01}, d.buffer) + assert.Equal(t, d.buffer, [8]byte{0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01}) d.Clear() - gobottest.Assert(t, [8]byte{}, d.buffer) + assert.Equal(t, d.buffer, [8]byte{}) } func TestAIP1640DriverSetIntensity(t *testing.T) { d := initTestAIP1640Driver() d.SetIntensity(3) - gobottest.Assert(t, uint8(3), d.intensity) + assert.Equal(t, d.intensity, uint8(3)) } func TestAIP1640DriverSetIntensityHigherThan7(t *testing.T) { d := initTestAIP1640Driver() d.SetIntensity(19) - gobottest.Assert(t, uint8(7), d.intensity) + assert.Equal(t, d.intensity, uint8(7)) } diff --git a/drivers/gpio/button_driver_test.go b/drivers/gpio/button_driver_test.go index aa458c88c..7455418cd 100644 --- a/drivers/gpio/button_driver_test.go +++ b/drivers/gpio/button_driver_test.go @@ -6,8 +6,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*ButtonDriver)(nil) @@ -23,15 +23,15 @@ func TestButtonDriverHalt(t *testing.T) { go func() { <-d.halt }() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestButtonDriver(t *testing.T) { d := NewButtonDriver(newGpioTestAdaptor(), "1") - gobottest.Refute(t, d.Connection(), nil) + assert.NotNil(t, d.Connection()) d = NewButtonDriver(newGpioTestAdaptor(), "1", 30*time.Second) - gobottest.Assert(t, d.interval, 30*time.Second) + assert.Equal(t, 30*time.Second, d.interval) } func TestButtonDriverStart(t *testing.T) { @@ -40,16 +40,16 @@ func TestButtonDriverStart(t *testing.T) { d := NewButtonDriver(a, "1") _ = d.Once(ButtonPush, func(data interface{}) { - gobottest.Assert(t, d.Active, true) + assert.True(t, d.Active) sem <- true }) - a.TestAdaptorDigitalRead(func(string) (val int, err error) { + a.digitalReadFunc = func(string) (val int, err error) { val = 1 return - }) + } - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) select { case <-sem: @@ -58,14 +58,14 @@ func TestButtonDriverStart(t *testing.T) { } _ = d.Once(ButtonRelease, func(data interface{}) { - gobottest.Assert(t, d.Active, false) + assert.False(t, d.Active) sem <- true }) - a.TestAdaptorDigitalRead(func(string) (val int, err error) { + a.digitalReadFunc = func(string) (val int, err error) { val = 0 return - }) + } select { case <-sem: @@ -77,10 +77,10 @@ func TestButtonDriverStart(t *testing.T) { sem <- true }) - a.TestAdaptorDigitalRead(func(string) (val int, err error) { + a.digitalReadFunc = func(string) (val int, err error) { err = errors.New("digital read error") return - }) + } select { case <-sem: @@ -94,10 +94,10 @@ func TestButtonDriverStart(t *testing.T) { d.halt <- true - a.TestAdaptorDigitalRead(func(string) (val int, err error) { + a.digitalReadFunc = func(string) (val int, err error) { val = 1 return - }) + } select { case <-sem: @@ -113,16 +113,16 @@ func TestButtonDriverDefaultState(t *testing.T) { d.DefaultState = 1 _ = d.Once(ButtonPush, func(data interface{}) { - gobottest.Assert(t, d.Active, true) + assert.True(t, d.Active) sem <- true }) - a.TestAdaptorDigitalRead(func(string) (val int, err error) { + a.digitalReadFunc = func(string) (val int, err error) { val = 0 return - }) + } - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) select { case <-sem: @@ -131,14 +131,14 @@ func TestButtonDriverDefaultState(t *testing.T) { } _ = d.Once(ButtonRelease, func(data interface{}) { - gobottest.Assert(t, d.Active, false) + assert.False(t, d.Active) sem <- true }) - a.TestAdaptorDigitalRead(func(string) (val int, err error) { + a.digitalReadFunc = func(string) (val int, err error) { val = 1 return - }) + } select { case <-sem: @@ -149,11 +149,11 @@ func TestButtonDriverDefaultState(t *testing.T) { func TestButtonDriverDefaultName(t *testing.T) { g := initTestButtonDriver() - gobottest.Assert(t, strings.HasPrefix(g.Name(), "Button"), true) + assert.True(t, strings.HasPrefix(g.Name(), "Button")) } func TestButtonDriverSetName(t *testing.T) { g := initTestButtonDriver() g.SetName("mybot") - gobottest.Assert(t, g.Name(), "mybot") + assert.Equal(t, "mybot", g.Name()) } diff --git a/drivers/gpio/buzzer_driver_test.go b/drivers/gpio/buzzer_driver_test.go index 3edb43ea5..b845813aa 100644 --- a/drivers/gpio/buzzer_driver_test.go +++ b/drivers/gpio/buzzer_driver_test.go @@ -5,8 +5,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*BuzzerDriver)(nil) @@ -17,65 +17,65 @@ func initTestBuzzerDriver(conn DigitalWriter) *BuzzerDriver { func TestBuzzerDriverDefaultName(t *testing.T) { g := initTestBuzzerDriver(newGpioTestAdaptor()) - gobottest.Assert(t, strings.HasPrefix(g.Name(), "Buzzer"), true) + assert.True(t, strings.HasPrefix(g.Name(), "Buzzer")) } func TestBuzzerDriverSetName(t *testing.T) { g := initTestBuzzerDriver(newGpioTestAdaptor()) g.SetName("mybot") - gobottest.Assert(t, g.Name(), "mybot") + assert.Equal(t, "mybot", g.Name()) } func TestBuzzerDriverStart(t *testing.T) { d := initTestBuzzerDriver(newGpioTestAdaptor()) - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestBuzzerDriverHalt(t *testing.T) { d := initTestBuzzerDriver(newGpioTestAdaptor()) - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestBuzzerDriverToggle(t *testing.T) { d := initTestBuzzerDriver(newGpioTestAdaptor()) _ = d.Off() _ = d.Toggle() - gobottest.Assert(t, d.State(), true) + assert.True(t, d.State()) _ = d.Toggle() - gobottest.Assert(t, d.State(), false) + assert.False(t, d.State()) } func TestBuzzerDriverTone(t *testing.T) { d := initTestBuzzerDriver(newGpioTestAdaptor()) - gobottest.Assert(t, d.Tone(100, 0.01), nil) + assert.NoError(t, d.Tone(100, 0.01)) } func TestBuzzerDriverOnError(t *testing.T) { a := newGpioTestAdaptor() d := initTestBuzzerDriver(a) - a.TestAdaptorDigitalWrite(func(string, byte) (err error) { + a.digitalWriteFunc = func(string, byte) (err error) { return errors.New("write error") - }) + } - gobottest.Assert(t, d.On(), errors.New("write error")) + assert.ErrorContains(t, d.On(), "write error") } func TestBuzzerDriverOffError(t *testing.T) { a := newGpioTestAdaptor() d := initTestBuzzerDriver(a) - a.TestAdaptorDigitalWrite(func(string, byte) (err error) { + a.digitalWriteFunc = func(string, byte) (err error) { return errors.New("write error") - }) + } - gobottest.Assert(t, d.Off(), errors.New("write error")) + assert.ErrorContains(t, d.Off(), "write error") } func TestBuzzerDriverToneError(t *testing.T) { a := newGpioTestAdaptor() d := initTestBuzzerDriver(a) - a.TestAdaptorDigitalWrite(func(string, byte) (err error) { + a.digitalWriteFunc = func(string, byte) (err error) { return errors.New("write error") - }) + } - gobottest.Assert(t, d.Tone(100, 0.01), errors.New("write error")) + assert.ErrorContains(t, d.Tone(100, 0.01), "write error") } diff --git a/drivers/gpio/direct_pin_driver_test.go b/drivers/gpio/direct_pin_driver_test.go index 2a0815a4e..7996eee28 100644 --- a/drivers/gpio/direct_pin_driver_test.go +++ b/drivers/gpio/direct_pin_driver_test.go @@ -5,25 +5,25 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*DirectPinDriver)(nil) func initTestDirectPinDriver() *DirectPinDriver { a := newGpioTestAdaptor() - a.testAdaptorDigitalRead = func(string) (val int, err error) { + a.digitalReadFunc = func(string) (val int, err error) { val = 1 return } - a.testAdaptorDigitalWrite = func(string, byte) (err error) { + a.digitalWriteFunc = func(string, byte) (err error) { return errors.New("write error") } - a.testAdaptorPwmWrite = func(string, byte) (err error) { + a.pwmWriteFunc = func(string, byte) (err error) { return errors.New("write error") } - a.testAdaptorServoWrite = func(string, byte) (err error) { + a.servoWriteFunc = func(string, byte) (err error) { return errors.New("write error") } return NewDirectPinDriver(a, "1") @@ -34,138 +34,138 @@ func TestDirectPinDriver(t *testing.T) { var err interface{} d := initTestDirectPinDriver() - gobottest.Assert(t, d.Pin(), "1") - gobottest.Refute(t, d.Connection(), nil) + assert.Equal(t, "1", d.Pin()) + assert.NotNil(t, d.Connection()) ret = d.Command("DigitalRead")(nil).(map[string]interface{}) - gobottest.Assert(t, ret["val"].(int), 1) - gobottest.Assert(t, ret["err"], nil) + assert.Equal(t, 1, ret["val"].(int)) + assert.Nil(t, ret["err"]) err = d.Command("DigitalWrite")(map[string]interface{}{"level": "1"}) - gobottest.Assert(t, err.(error), errors.New("write error")) + assert.ErrorContains(t, err.(error), "write error") err = d.Command("PwmWrite")(map[string]interface{}{"level": "1"}) - gobottest.Assert(t, err.(error), errors.New("write error")) + assert.ErrorContains(t, err.(error), "write error") err = d.Command("ServoWrite")(map[string]interface{}{"level": "1"}) - gobottest.Assert(t, err.(error), errors.New("write error")) + assert.ErrorContains(t, err.(error), "write error") } func TestDirectPinDriverStart(t *testing.T) { d := initTestDirectPinDriver() - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestDirectPinDriverHalt(t *testing.T) { d := initTestDirectPinDriver() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestDirectPinDriverOff(t *testing.T) { d := initTestDirectPinDriver() - gobottest.Refute(t, d.Off(), nil) + assert.NotNil(t, d.Off()) a := newGpioTestAdaptor() d = NewDirectPinDriver(a, "1") - gobottest.Assert(t, d.Off(), nil) + assert.NoError(t, d.Off()) } func TestDirectPinDriverOffNotSupported(t *testing.T) { a := &gpioTestBareAdaptor{} d := NewDirectPinDriver(a, "1") - gobottest.Assert(t, d.Off(), errors.New("DigitalWrite is not supported by this platform")) + assert.ErrorContains(t, d.Off(), "DigitalWrite is not supported by this platform") } func TestDirectPinDriverOn(t *testing.T) { a := newGpioTestAdaptor() d := NewDirectPinDriver(a, "1") - gobottest.Assert(t, d.On(), nil) + assert.NoError(t, d.On()) } func TestDirectPinDriverOnError(t *testing.T) { d := initTestDirectPinDriver() - gobottest.Refute(t, d.On(), nil) + assert.NotNil(t, d.On()) } func TestDirectPinDriverOnNotSupported(t *testing.T) { a := &gpioTestBareAdaptor{} d := NewDirectPinDriver(a, "1") - gobottest.Assert(t, d.On(), errors.New("DigitalWrite is not supported by this platform")) + assert.ErrorContains(t, d.On(), "DigitalWrite is not supported by this platform") } func TestDirectPinDriverDigitalWrite(t *testing.T) { adaptor := newGpioTestAdaptor() d := NewDirectPinDriver(adaptor, "1") - gobottest.Assert(t, d.DigitalWrite(1), nil) + assert.NoError(t, d.DigitalWrite(1)) } func TestDirectPinDriverDigitalWriteNotSupported(t *testing.T) { a := &gpioTestBareAdaptor{} d := NewDirectPinDriver(a, "1") - gobottest.Assert(t, d.DigitalWrite(1), errors.New("DigitalWrite is not supported by this platform")) + assert.ErrorContains(t, d.DigitalWrite(1), "DigitalWrite is not supported by this platform") } func TestDirectPinDriverDigitalWriteError(t *testing.T) { d := initTestDirectPinDriver() - gobottest.Refute(t, d.DigitalWrite(1), nil) + assert.NotNil(t, d.DigitalWrite(1)) } func TestDirectPinDriverDigitalRead(t *testing.T) { d := initTestDirectPinDriver() ret, err := d.DigitalRead() - gobottest.Assert(t, ret, 1) - gobottest.Assert(t, err, nil) + assert.Equal(t, 1, ret) + assert.NoError(t, err) } func TestDirectPinDriverDigitalReadNotSupported(t *testing.T) { a := &gpioTestBareAdaptor{} d := NewDirectPinDriver(a, "1") _, e := d.DigitalRead() - gobottest.Assert(t, e, errors.New("DigitalRead is not supported by this platform")) + assert.ErrorContains(t, e, "DigitalRead is not supported by this platform") } func TestDirectPinDriverPwmWrite(t *testing.T) { a := newGpioTestAdaptor() d := NewDirectPinDriver(a, "1") - gobottest.Assert(t, d.PwmWrite(1), nil) + assert.NoError(t, d.PwmWrite(1)) } func TestDirectPinDriverPwmWriteNotSupported(t *testing.T) { a := &gpioTestBareAdaptor{} d := NewDirectPinDriver(a, "1") - gobottest.Assert(t, d.PwmWrite(1), errors.New("PwmWrite is not supported by this platform")) + assert.ErrorContains(t, d.PwmWrite(1), "PwmWrite is not supported by this platform") } func TestDirectPinDriverPwmWriteError(t *testing.T) { d := initTestDirectPinDriver() - gobottest.Refute(t, d.PwmWrite(1), nil) + assert.NotNil(t, d.PwmWrite(1)) } func TestDirectPinDriverServoWrite(t *testing.T) { a := newGpioTestAdaptor() d := NewDirectPinDriver(a, "1") - gobottest.Assert(t, d.ServoWrite(1), nil) + assert.NoError(t, d.ServoWrite(1)) } func TestDirectPinDriverServoWriteNotSupported(t *testing.T) { a := &gpioTestBareAdaptor{} d := NewDirectPinDriver(a, "1") - gobottest.Assert(t, d.ServoWrite(1), errors.New("ServoWrite is not supported by this platform")) + assert.ErrorContains(t, d.ServoWrite(1), "ServoWrite is not supported by this platform") } func TestDirectPinDriverServoWriteError(t *testing.T) { d := initTestDirectPinDriver() - gobottest.Refute(t, d.ServoWrite(1), nil) + assert.NotNil(t, d.ServoWrite(1)) } func TestDirectPinDriverDefaultName(t *testing.T) { d := initTestDirectPinDriver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "Direct"), true) + assert.True(t, strings.HasPrefix(d.Name(), "Direct")) } func TestDirectPinDriverSetName(t *testing.T) { d := initTestDirectPinDriver() d.SetName("mybot") - gobottest.Assert(t, d.Name(), "mybot") + assert.Equal(t, "mybot", d.Name()) } diff --git a/drivers/gpio/easy_driver_test.go b/drivers/gpio/easy_driver_test.go index baaf69170..669aeeb7b 100644 --- a/drivers/gpio/easy_driver_test.go +++ b/drivers/gpio/easy_driver_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) const ( @@ -22,18 +22,18 @@ func initEasyDriver() *EasyDriver { func TestEasyDriver_Connection(t *testing.T) { d := initEasyDriver() - gobottest.Assert(t, d.Connection(), adapter) + assert.Equal(t, adapter, d.Connection()) } func TestEasyDriverDefaultName(t *testing.T) { d := initEasyDriver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "EasyDriver"), true) + assert.True(t, strings.HasPrefix(d.Name(), "EasyDriver")) } func TestEasyDriverSetName(t *testing.T) { d := initEasyDriver() d.SetName("OtherDriver") - gobottest.Assert(t, strings.HasPrefix(d.Name(), "OtherDriver"), true) + assert.True(t, strings.HasPrefix(d.Name(), "OtherDriver")) } func TestEasyDriverStart(t *testing.T) { @@ -45,142 +45,142 @@ func TestEasyDriverStart(t *testing.T) { func TestEasyDriverHalt(t *testing.T) { d := initEasyDriver() _ = d.Run() - gobottest.Assert(t, d.IsMoving(), true) + assert.True(t, d.IsMoving()) _ = d.Halt() - gobottest.Assert(t, d.IsMoving(), false) + assert.False(t, d.IsMoving()) } func TestEasyDriverMove(t *testing.T) { d := initEasyDriver() _ = d.Move(2) time.Sleep(2 * time.Millisecond) - gobottest.Assert(t, d.GetCurrentStep(), 4) - gobottest.Assert(t, d.IsMoving(), false) + assert.Equal(t, 4, d.GetCurrentStep()) + assert.False(t, d.IsMoving()) } func TestEasyDriverRun(t *testing.T) { d := initEasyDriver() _ = d.Run() - gobottest.Assert(t, d.IsMoving(), true) + assert.True(t, d.IsMoving()) _ = d.Run() - gobottest.Assert(t, d.IsMoving(), true) + assert.True(t, d.IsMoving()) } func TestEasyDriverStop(t *testing.T) { d := initEasyDriver() _ = d.Run() - gobottest.Assert(t, d.IsMoving(), true) + assert.True(t, d.IsMoving()) _ = d.Stop() - gobottest.Assert(t, d.IsMoving(), false) + assert.False(t, d.IsMoving()) } func TestEasyDriverStep(t *testing.T) { d := initEasyDriver() _ = d.Step() - gobottest.Assert(t, d.GetCurrentStep(), 1) + assert.Equal(t, 1, d.GetCurrentStep()) _ = d.Step() _ = d.Step() _ = d.Step() - gobottest.Assert(t, d.GetCurrentStep(), 4) + assert.Equal(t, 4, d.GetCurrentStep()) _ = d.SetDirection("ccw") _ = d.Step() - gobottest.Assert(t, d.GetCurrentStep(), 3) + assert.Equal(t, 3, d.GetCurrentStep()) } func TestEasyDriverSetDirection(t *testing.T) { d := initEasyDriver() - gobottest.Assert(t, d.dir, int8(1)) + assert.Equal(t, int8(1), d.dir) _ = d.SetDirection("cw") - gobottest.Assert(t, d.dir, int8(1)) + assert.Equal(t, int8(1), d.dir) _ = d.SetDirection("ccw") - gobottest.Assert(t, d.dir, int8(-1)) + assert.Equal(t, int8(-1), d.dir) _ = d.SetDirection("nothing") - gobottest.Assert(t, d.dir, int8(1)) + assert.Equal(t, int8(1), d.dir) } func TestEasyDriverSetDirectionNoPin(t *testing.T) { d := initEasyDriver() d.dirPin = "" err := d.SetDirection("cw") - gobottest.Refute(t, err, nil) + assert.NotNil(t, err) } func TestEasyDriverSetSpeed(t *testing.T) { d := initEasyDriver() - gobottest.Assert(t, d.rpm, uint(stepsPerRev/4)) // default speed of 720/4 + assert.Equal(t, uint(stepsPerRev/4), d.rpm) // default speed of 720/4 _ = d.SetSpeed(0) - gobottest.Assert(t, d.rpm, uint(1)) + assert.Equal(t, uint(1), d.rpm) _ = d.SetSpeed(200) - gobottest.Assert(t, d.rpm, uint(200)) + assert.Equal(t, uint(200), d.rpm) _ = d.SetSpeed(1000) - gobottest.Assert(t, d.rpm, uint(stepsPerRev)) + assert.Equal(t, uint(stepsPerRev), d.rpm) } func TestEasyDriverGetMaxSpeed(t *testing.T) { d := initEasyDriver() - gobottest.Assert(t, d.GetMaxSpeed(), uint(stepsPerRev)) + assert.Equal(t, uint(stepsPerRev), d.GetMaxSpeed()) } func TestEasyDriverSleep(t *testing.T) { // let's test basic functionality d := initEasyDriver() _ = d.Sleep() - gobottest.Assert(t, d.IsSleeping(), true) + assert.True(t, d.IsSleeping()) // let's make sure it stops first d = initEasyDriver() _ = d.Run() _ = d.Sleep() - gobottest.Assert(t, d.IsSleeping(), true) - gobottest.Assert(t, d.IsMoving(), false) + assert.True(t, d.IsSleeping()) + assert.False(t, d.IsMoving()) } func TestEasyDriverSleepNoPin(t *testing.T) { d := initEasyDriver() d.sleepPin = "" err := d.Sleep() - gobottest.Refute(t, err, nil) + assert.NotNil(t, err) err = d.Wake() - gobottest.Refute(t, err, nil) + assert.NotNil(t, err) } func TestEasyDriverWake(t *testing.T) { // let's test basic functionality d := initEasyDriver() _ = d.Sleep() - gobottest.Assert(t, d.IsSleeping(), true) + assert.True(t, d.IsSleeping()) _ = d.Wake() - gobottest.Assert(t, d.IsSleeping(), false) + assert.False(t, d.IsSleeping()) } func TestEasyDriverEnable(t *testing.T) { // let's test basic functionality d := initEasyDriver() _ = d.Disable() - gobottest.Assert(t, d.IsEnabled(), false) + assert.False(t, d.IsEnabled()) _ = d.Enable() - gobottest.Assert(t, d.IsEnabled(), true) + assert.True(t, d.IsEnabled()) } func TestEasyDriverEnableNoPin(t *testing.T) { d := initEasyDriver() d.enPin = "" err := d.Disable() - gobottest.Refute(t, err, nil) + assert.NotNil(t, err) err = d.Enable() - gobottest.Refute(t, err, nil) + assert.NotNil(t, err) } func TestEasyDriverDisable(t *testing.T) { // let's test basic functionality d := initEasyDriver() _ = d.Disable() - gobottest.Assert(t, d.IsEnabled(), false) + assert.False(t, d.IsEnabled()) // let's make sure it stops first d = initEasyDriver() _ = d.Run() _ = d.Disable() - gobottest.Assert(t, d.IsEnabled(), false) - gobottest.Assert(t, d.IsMoving(), false) + assert.False(t, d.IsEnabled()) + assert.False(t, d.IsMoving()) } diff --git a/drivers/gpio/gpio.go b/drivers/gpio/gpio_driver.go similarity index 62% rename from drivers/gpio/gpio.go rename to drivers/gpio/gpio_driver.go index 624cca19f..bc09ae0a7 100644 --- a/drivers/gpio/gpio.go +++ b/drivers/gpio/gpio_driver.go @@ -2,6 +2,9 @@ package gpio import ( "errors" + "sync" + + "gobot.io/x/gobot/v2" ) var ( @@ -61,3 +64,62 @@ type DigitalWriter interface { type DigitalReader interface { DigitalRead(string) (val int, err error) } + +// Driver implements the interface gobot.Driver. +type Driver struct { + name string + connection gobot.Adaptor + afterStart func() error + beforeHalt func() error + gobot.Commander + mutex *sync.Mutex // mutex often needed to ensure that write-read sequences are not interrupted +} + +// NewDriver creates a new generic and basic gpio gobot driver. +func NewDriver(a gobot.Adaptor, name string) *Driver { + d := &Driver{ + name: gobot.DefaultName(name), + connection: a, + afterStart: func() error { return nil }, + beforeHalt: func() error { return nil }, + Commander: gobot.NewCommander(), + mutex: &sync.Mutex{}, + } + + return d +} + +// Name returns the name of the gpio device. +func (d *Driver) Name() string { + return d.name +} + +// SetName sets the name of the gpio device. +func (d *Driver) SetName(name string) { + d.name = name +} + +// Connection returns the connection of the gpio device. +func (d *Driver) Connection() gobot.Connection { + return d.connection.(gobot.Connection) +} + +// Start initializes the gpio device. +func (d *Driver) Start() error { + d.mutex.Lock() + defer d.mutex.Unlock() + + // currently there is nothing to do here for the driver + + return d.afterStart() +} + +// Halt halts the gpio device. +func (d *Driver) Halt() error { + d.mutex.Lock() + defer d.mutex.Unlock() + + // currently there is nothing to do after halt for the driver + + return d.beforeHalt() +} diff --git a/drivers/gpio/gpio_driver_test.go b/drivers/gpio/gpio_driver_test.go new file mode 100644 index 000000000..30ae59bbc --- /dev/null +++ b/drivers/gpio/gpio_driver_test.go @@ -0,0 +1,78 @@ +package gpio + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "gobot.io/x/gobot/v2" +) + +var _ gobot.Driver = (*Driver)(nil) + +func initTestDriverWithStubbedAdaptor() (*Driver, *gpioTestAdaptor) { + a := newGpioTestAdaptor() + d := NewDriver(a, "GPIO_BASIC") + return d, a +} + +func initTestDriver() *Driver { + d, _ := initTestDriverWithStubbedAdaptor() + return d +} + +func TestNewDriver(t *testing.T) { + // arrange + a := newGpioTestAdaptor() + // act + var di interface{} = NewDriver(a, "GPIO_BASIC") + // assert + d, ok := di.(*Driver) + if !ok { + t.Errorf("NewDriver() should have returned a *Driver") + } + assert.Contains(t, d.name, "GPIO_BASIC") + assert.Equal(t, a, d.connection) + assert.NoError(t, d.afterStart()) + assert.NoError(t, d.beforeHalt()) + assert.NotNil(t, d.Commander) + assert.NotNil(t, d.mutex) +} + +func TestSetName(t *testing.T) { + // arrange + d := initTestDriver() + // act + d.SetName("TESTME") + // assert + assert.Equal(t, "TESTME", d.Name()) +} + +func TestConnection(t *testing.T) { + // arrange + d, a := initTestDriverWithStubbedAdaptor() + // act, assert + assert.Equal(t, a, d.Connection()) +} + +func TestStart(t *testing.T) { + // arrange + d := initTestDriver() + // act, assert + assert.NoError(t, d.Start()) + // arrange after start function + d.afterStart = func() error { return fmt.Errorf("after start error") } + // act, assert + assert.ErrorContains(t, d.Start(), "after start error") +} + +func TestHalt(t *testing.T) { + // arrange + d := initTestDriver() + // act, assert + assert.NoError(t, d.Halt()) + // arrange after start function + d.beforeHalt = func() error { return fmt.Errorf("before halt error") } + // act, assert + assert.ErrorContains(t, d.Halt(), "before halt error") +} diff --git a/drivers/gpio/grove_drivers.go b/drivers/gpio/grove_drivers.go index 80f1ab377..017fa7338 100644 --- a/drivers/gpio/grove_drivers.go +++ b/drivers/gpio/grove_drivers.go @@ -12,6 +12,7 @@ type GroveRelayDriver struct { // NewGroveRelayDriver return a new GroveRelayDriver given a DigitalWriter and pin. // // Adds the following API Commands: +// // "Toggle" - See RelayDriver.Toggle // "On" - See RelayDriver.On // "Off" - See RelayDriver.Off @@ -29,6 +30,7 @@ type GroveLedDriver struct { // NewGroveLedDriver return a new GroveLedDriver given a DigitalWriter and pin. // // Adds the following API Commands: +// // "Brightness" - See LedDriver.Brightness // "Toggle" - See LedDriver.Toggle // "On" - See LedDriver.On @@ -62,7 +64,8 @@ type GroveButtonDriver struct { // 10 Milliseconds given a DigitalReader and pin. // // Optionally accepts: -// time.Duration: Interval at which the ButtonDriver is polled for new information +// +// time.Duration: Interval at which the ButtonDriver is polled for new information func NewGroveButtonDriver(a DigitalReader, pin string, v ...time.Duration) *GroveButtonDriver { return &GroveButtonDriver{ ButtonDriver: NewButtonDriver(a, pin, v...), @@ -79,7 +82,8 @@ type GroveTouchDriver struct { // 10 Milliseconds given a DigitalReader and pin. // // Optionally accepts: -// time.Duration: Interval at which the ButtonDriver is polled for new information +// +// time.Duration: Interval at which the ButtonDriver is polled for new information func NewGroveTouchDriver(a DigitalReader, pin string, v ...time.Duration) *GroveTouchDriver { return &GroveTouchDriver{ ButtonDriver: NewButtonDriver(a, pin, v...), @@ -96,7 +100,8 @@ type GroveMagneticSwitchDriver struct { // 10 Milliseconds given a DigitalReader, name and pin. // // Optionally accepts: -// time.Duration: Interval at which the ButtonDriver is polled for new information +// +// time.Duration: Interval at which the ButtonDriver is polled for new information func NewGroveMagneticSwitchDriver(a DigitalReader, pin string, v ...time.Duration) *GroveMagneticSwitchDriver { return &GroveMagneticSwitchDriver{ ButtonDriver: NewButtonDriver(a, pin, v...), diff --git a/drivers/gpio/grove_drivers_test.go b/drivers/gpio/grove_drivers_test.go index 35f3ac840..d580fc51f 100644 --- a/drivers/gpio/grove_drivers_test.go +++ b/drivers/gpio/grove_drivers_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) type DriverAndPinner interface { @@ -35,8 +35,8 @@ func TestDriverDefaults(t *testing.T) { } for _, driver := range drivers { - gobottest.Assert(t, driver.Connection(), testAdaptor) - gobottest.Assert(t, driver.Pin(), pin) + assert.Equal(t, testAdaptor, driver.Connection()) + assert.Equal(t, pin, driver.Pin()) } } @@ -53,7 +53,7 @@ func TestDigitalDriverHalt(t *testing.T) { for _, driver := range drivers { var callCount int32 - testAdaptor.testAdaptorDigitalRead = func(string) (int, error) { + testAdaptor.digitalReadFunc = func(string) (int, error) { atomic.AddInt32(&callCount, 1) return 42, nil } @@ -89,13 +89,13 @@ func TestDriverPublishesError(t *testing.T) { err = errors.New("read error") return } - testAdaptor.testAdaptorDigitalRead = returnErr + testAdaptor.digitalReadFunc = returnErr - gobottest.Assert(t, driver.Start(), nil) + assert.NoError(t, driver.Start()) // expect error _ = driver.Once(driver.Event(Error), func(data interface{}) { - gobottest.Assert(t, data.(error).Error(), "read error") + assert.Equal(t, "read error", data.(error).Error()) close(sem) }) diff --git a/drivers/gpio/hcsr04_driver.go b/drivers/gpio/hcsr04_driver.go new file mode 100644 index 000000000..471c055a4 --- /dev/null +++ b/drivers/gpio/hcsr04_driver.go @@ -0,0 +1,218 @@ +package gpio + +import ( + "fmt" + "sync" + "time" + + "gobot.io/x/gobot/v2" + "gobot.io/x/gobot/v2/system" +) + +const ( + hcsr04SoundSpeed = 343 // in [m/s] + // the device can measure 2 cm .. 4 m, this means sweep distances between 4 cm and 8 m + // this cause pulse duration between 0.12 ms and 24 ms (at 34.3 cm/ms, ~0.03 ms/cm, ~3 ms/m) + // so we use 60 ms as a limit for timeout and 100 ms for duration between 2 consecutive measurements + hcsr04StartTransmitTimeout time.Duration = 100 * time.Millisecond // unfortunately takes sometimes longer than 60 ms + hcsr04ReceiveTimeout time.Duration = 60 * time.Millisecond + hcsr04EmitTriggerDuration time.Duration = 10 * time.Microsecond // according to specification + hcsr04MonitorUpdate time.Duration = 200 * time.Millisecond + // the resolution of the device is ~3 mm, which relates to 10 us (343 mm/ms = 0.343 mm/us) + // the poll interval increases the reading interval to this value and adds around 3 mm inaccuracy + // it takes only an effect for fast systems, because reading inputs is typically much slower, e.g. 30-50 us on raspi + // so, using the internal edge detection with "cdev" is more precise + hcsr04PollInputIntervall time.Duration = 10 * time.Microsecond +) + +// HCSR04Driver is a driver for ultrasonic range measurement. +type HCSR04Driver struct { + *Driver + triggerPinID string + echoPinID string + useEdgePolling bool // use discrete edge polling instead "cdev" from gpiod + measureMutex *sync.Mutex // to ensure that only one measurement is done at a time + triggerPin gobot.DigitalPinner + echoPin gobot.DigitalPinner + lastMeasureMicroSec int64 // ~120 .. 24000 us + distanceMonitorStopChan chan struct{} + distanceMonitorStopWaitGroup *sync.WaitGroup + delayMicroSecChan chan int64 // channel for event handler return value + pollQuitChan chan struct{} // channel for quit the continuous polling +} + +// NewHCSR04Driver creates a new instance of the driver for HC-SR04 (same as SEN-US01). +// +// Datasheet: https://www.makershop.de/download/HCSR04-datasheet-version-1.pdf +func NewHCSR04Driver(a gobot.Adaptor, triggerPinID string, echoPinID string, useEdgePolling bool) *HCSR04Driver { + h := HCSR04Driver{ + Driver: NewDriver(a, "HCSR04"), + triggerPinID: triggerPinID, + echoPinID: echoPinID, + useEdgePolling: useEdgePolling, + measureMutex: &sync.Mutex{}, + } + + h.afterStart = func() error { + tpin, err := a.(gobot.DigitalPinnerProvider).DigitalPin(triggerPinID) + if err != nil { + return fmt.Errorf("error on get trigger pin: %v", err) + } + if err := tpin.ApplyOptions(system.WithPinDirectionOutput(0)); err != nil { + return fmt.Errorf("error on apply output for trigger pin: %v", err) + } + h.triggerPin = tpin + + // pins are inputs by default + epin, err := a.(gobot.DigitalPinnerProvider).DigitalPin(echoPinID) + if err != nil { + return fmt.Errorf("error on get echo pin: %v", err) + } + + epinOptions := []func(gobot.DigitalPinOptioner) bool{system.WithPinEventOnBothEdges(h.createEventHandler())} + if h.useEdgePolling { + h.pollQuitChan = make(chan struct{}) + epinOptions = append(epinOptions, system.WithPinPollForEdgeDetection(hcsr04PollInputIntervall, h.pollQuitChan)) + } + if err := epin.ApplyOptions(epinOptions...); err != nil { + return fmt.Errorf("error on apply options for echo pin: %v", err) + } + h.echoPin = epin + + h.delayMicroSecChan = make(chan int64) + + return nil + } + + h.beforeHalt = func() error { + if useEdgePolling { + close(h.pollQuitChan) + } + + if err := h.stopDistanceMonitor(); err != nil { + fmt.Printf("no need to stop distance monitoring: %v\n", err) + } + + // note: Unexport() of all pins will be done on adaptor.Finalize() + + close(h.delayMicroSecChan) + + return nil + } + + return &h +} + +// MeasureDistance retrieves the distance in front of sensor in meters and returns the measure. It is not designed +// to work in a fast loop! For this specific usage, use StartDistanceMonitor() associated with Distance() instead. +func (h *HCSR04Driver) MeasureDistance() (float64, error) { + err := h.measureDistance() + if err != nil { + return 0, err + } + return h.Distance(), nil +} + +// Distance returns the last distance measured in meter, it does not trigger a distance measurement +func (h *HCSR04Driver) Distance() float64 { + distMm := h.lastMeasureMicroSec * hcsr04SoundSpeed / 1000 / 2 + return float64(distMm) / 1000.0 +} + +// StartDistanceMonitor starts continuous measurement. The current value can be read by Distance() +func (h *HCSR04Driver) StartDistanceMonitor() error { + // ensure that start and stop can not interfere + h.mutex.Lock() + defer h.mutex.Unlock() + + if h.distanceMonitorStopChan != nil { + return fmt.Errorf("distance monitor already started for '%s'", h.name) + } + + h.distanceMonitorStopChan = make(chan struct{}) + h.distanceMonitorStopWaitGroup = &sync.WaitGroup{} + h.distanceMonitorStopWaitGroup.Add(1) + + go func(name string) { + defer h.distanceMonitorStopWaitGroup.Done() + for { + select { + case <-h.distanceMonitorStopChan: + h.distanceMonitorStopChan = nil + return + default: + if err := h.measureDistance(); err != nil { + fmt.Printf("continuous measure distance skipped for '%s': %v\n", name, err) + } + time.Sleep(hcsr04MonitorUpdate) + } + } + }(h.name) + + return nil +} + +// StopDistanceMonitor stop the monitor process +func (h *HCSR04Driver) StopDistanceMonitor() error { + // ensure that start and stop can not interfere + h.mutex.Lock() + defer h.mutex.Unlock() + + return h.stopDistanceMonitor() +} + +func (h *HCSR04Driver) createEventHandler() func(int, time.Duration, string, uint32, uint32) { + var startTimestamp time.Duration + return func(offset int, t time.Duration, et string, sn uint32, lsn uint32) { + switch et { + case system.DigitalPinEventRisingEdge: + startTimestamp = t + case system.DigitalPinEventFallingEdge: + // unfortunately there is an additional falling edge at each start trigger, so we need to filter this + // we use the start duration value for filtering + if startTimestamp == 0 { + return + } + h.delayMicroSecChan <- (t - startTimestamp).Microseconds() + startTimestamp = 0 + } + } +} + +func (h *HCSR04Driver) stopDistanceMonitor() error { + if h.distanceMonitorStopChan == nil { + return fmt.Errorf("distance monitor is not yet started for '%s'", h.name) + } + + h.distanceMonitorStopChan <- struct{}{} + h.distanceMonitorStopWaitGroup.Wait() + + return nil +} + +func (h *HCSR04Driver) measureDistance() error { + h.measureMutex.Lock() + defer h.measureMutex.Unlock() + + if err := h.emitTrigger(); err != nil { + return err + } + + // stop the loop if the measure is done or the timeout is elapsed + timeout := hcsr04StartTransmitTimeout + hcsr04ReceiveTimeout + select { + case <-time.After(timeout): + return fmt.Errorf("timeout %s reached while waiting for value with echo pin %s", timeout, h.echoPinID) + case h.lastMeasureMicroSec = <-h.delayMicroSecChan: + } + + return nil +} + +func (h *HCSR04Driver) emitTrigger() error { + if err := h.triggerPin.Write(1); err != nil { + return err + } + time.Sleep(hcsr04EmitTriggerDuration) + return h.triggerPin.Write(0) +} diff --git a/drivers/gpio/hcsr04_driver_test.go b/drivers/gpio/hcsr04_driver_test.go new file mode 100644 index 000000000..994600a55 --- /dev/null +++ b/drivers/gpio/hcsr04_driver_test.go @@ -0,0 +1,338 @@ +package gpio + +import ( + "fmt" + "strings" + "sync" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gobot.io/x/gobot/v2/system" +) + +func initTestHCSR04DriverWithStubbedAdaptor(triggerPinID string, echoPinID string) (*HCSR04Driver, *digitalPinMock) { + a := newGpioTestAdaptor() + tpin := a.addDigitalPin(triggerPinID) + _ = a.addDigitalPin(echoPinID) + d := NewHCSR04Driver(a, triggerPinID, echoPinID, false) + if err := d.Start(); err != nil { + panic(err) + } + return d, tpin +} + +func TestNewHCSR04Driver(t *testing.T) { + // arrange + const ( + triggerPinID = "3" + echoPinID = "4" + ) + a := newGpioTestAdaptor() + tpin := a.addDigitalPin(triggerPinID) + epin := a.addDigitalPin(echoPinID) + // act + d := NewHCSR04Driver(a, triggerPinID, echoPinID, false) + // assert + assert.IsType(t, &HCSR04Driver{}, d) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.name, "HCSR04")) + assert.Equal(t, a, d.connection) + assert.NoError(t, d.afterStart()) + assert.NoError(t, d.beforeHalt()) + assert.NotNil(t, d.Commander) + assert.NotNil(t, d.mutex) + assert.Equal(t, triggerPinID, d.triggerPinID) + assert.Equal(t, echoPinID, d.echoPinID) + assert.Equal(t, false, d.useEdgePolling) + assert.Equal(t, tpin, d.triggerPin) + assert.Equal(t, epin, d.echoPin) +} + +func TestHCSR04MeasureDistance(t *testing.T) { + tests := map[string]struct { + measureMicroSec int64 + simulateWriteErr string + wantCallsWrite int + wantVal float64 + wantErr string + }{ + "measure_ok": { + measureMicroSec: 5831, + wantCallsWrite: 2, + wantVal: 1.0, + }, + "error_timeout": { + measureMicroSec: 170000, // > 160 ms + wantCallsWrite: 2, + wantErr: "timeout 160ms reached", + }, + "error_write": { + measureMicroSec: 5831, + simulateWriteErr: "write error", + wantCallsWrite: 1, + wantErr: "write error", + }, + } + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + // arrange + d, tpin := initTestHCSR04DriverWithStubbedAdaptor("3", "4") + // arrange sensor and event handler simulation + waitForTriggerChan := make(chan struct{}) + loopWg := sync.WaitGroup{} + defer func() { + close(waitForTriggerChan) + loopWg.Wait() + }() + loopWg.Add(1) + go func() { + <-waitForTriggerChan + m := tc.measureMicroSec // to prevent data race together with wait group + loopWg.Done() + time.Sleep(time.Duration(m) * time.Microsecond) + d.delayMicroSecChan <- m + }() + // arrange writes + numCallsWrite := 0 + var oldVal int + tpin.writeFunc = func(val int) error { + numCallsWrite++ + if val == 0 && oldVal == 1 { + // falling edge detected + waitForTriggerChan <- struct{}{} + } + oldVal = val + var err error + if tc.simulateWriteErr != "" { + err = fmt.Errorf(tc.simulateWriteErr) + } + return err + } + // act + got, err := d.MeasureDistance() + // assert + assert.Equal(t, tc.wantCallsWrite, numCallsWrite) + if tc.wantErr != "" { + assert.ErrorContains(t, err, tc.wantErr) + } else { + require.NoError(t, err) + } + assert.Equal(t, tc.wantVal, got) + }) + } +} + +func TestHCSR04Distance(t *testing.T) { + tests := map[string]struct { + measureMicroSec int64 + simulateWriteErr string + wantVal float64 + wantErr string + }{ + "distance_0mm": { + measureMicroSec: 0, // no validity test yet + wantVal: 0.0, + }, + "distance_2cm": { + measureMicroSec: 117, // 117us ~ 0.12ms => ~2cm + wantVal: 0.02, + }, + "distance_4m": { + measureMicroSec: 23324, // 23324us ~ 24ms => ~4m + wantVal: 4.0, + }, + } + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + // arrange + d := HCSR04Driver{lastMeasureMicroSec: tc.measureMicroSec} + // act + got := d.Distance() + // assert + assert.Equal(t, tc.wantVal, got) + }) + } +} + +func TestHCSR04StartDistanceMonitor(t *testing.T) { + tests := map[string]struct { + simulateIsStarted bool + simulateWriteErr bool + wantErr string + }{ + "start_ok": {}, + "start_ok_measure_error": { + simulateWriteErr: true, + }, + "error_already_started": { + simulateIsStarted: true, + wantErr: "already started for 'HCSR04-", + }, + } + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + // arrange + d, tpin := initTestHCSR04DriverWithStubbedAdaptor("3", "4") + defer func() { + if d.distanceMonitorStopChan != nil { + close(d.distanceMonitorStopChan) + } + if d.distanceMonitorStopWaitGroup != nil { + d.distanceMonitorStopWaitGroup.Wait() + } + }() + if tc.simulateIsStarted { + d.distanceMonitorStopChan = make(chan struct{}) + } + tpin.writeFunc = func(val int) error { + if tc.simulateWriteErr { + return fmt.Errorf("write error") + } + return nil + } + // act + err := d.StartDistanceMonitor() + time.Sleep(1 * time.Millisecond) // < 160 ms + // assert + if tc.wantErr != "" { + assert.ErrorContains(t, err, tc.wantErr) + } else { + require.NoError(t, err) + assert.NotNil(t, d.distanceMonitorStopChan) + assert.NotNil(t, d.distanceMonitorStopWaitGroup) + } + }) + } +} + +func TestHCSR04StopDistanceMonitor(t *testing.T) { + tests := map[string]struct { + start bool + wantErr string + }{ + "stop_ok": { + start: true, + }, + "error_not_started": { + wantErr: "not yet started for 'HCSR04-", + }, + } + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + // arrange + d, _ := initTestHCSR04DriverWithStubbedAdaptor("3", "4") + defer func() { + if d.distanceMonitorStopChan != nil { + close(d.distanceMonitorStopChan) + } + if d.distanceMonitorStopWaitGroup != nil { + d.distanceMonitorStopWaitGroup.Wait() + } + }() + if tc.start { + err := d.StartDistanceMonitor() + require.NoError(t, err) + } + // act + err := d.StopDistanceMonitor() + time.Sleep(1 * time.Millisecond) // < 160 ms + // assert + if tc.wantErr != "" { + assert.ErrorContains(t, err, tc.wantErr) + } else { + require.NoError(t, err) + assert.Nil(t, d.distanceMonitorStopChan) + } + }) + } +} + +func TestHCSR04_createEventHandler(t *testing.T) { + type eventCall struct { + timeStamp time.Duration + eventType string + } + tests := map[string]struct { + calls []eventCall + wants []int64 + }{ + "only_rising": { + calls: []eventCall{ + {timeStamp: 1 * time.Microsecond, eventType: system.DigitalPinEventRisingEdge}, + {timeStamp: 2 * time.Microsecond, eventType: system.DigitalPinEventRisingEdge}, + }, + }, + "only_falling": { + calls: []eventCall{ + {timeStamp: 2 * time.Microsecond, eventType: system.DigitalPinEventFallingEdge}, + {timeStamp: 3 * time.Microsecond, eventType: system.DigitalPinEventFallingEdge}, + }, + }, + "event_normal": { + calls: []eventCall{ + {timeStamp: 1 * time.Microsecond, eventType: system.DigitalPinEventRisingEdge}, + {timeStamp: 10 * time.Microsecond, eventType: system.DigitalPinEventFallingEdge}, + }, + wants: []int64{9}, + }, + "event_falling_before": { + calls: []eventCall{ + {timeStamp: 1 * time.Microsecond, eventType: system.DigitalPinEventFallingEdge}, + {timeStamp: 2 * time.Microsecond, eventType: system.DigitalPinEventRisingEdge}, + {timeStamp: 10 * time.Microsecond, eventType: system.DigitalPinEventFallingEdge}, + }, + wants: []int64{8}, + }, + "event_falling_after": { + calls: []eventCall{ + {timeStamp: 1 * time.Microsecond, eventType: system.DigitalPinEventRisingEdge}, + {timeStamp: 10 * time.Microsecond, eventType: system.DigitalPinEventFallingEdge}, + {timeStamp: 12 * time.Microsecond, eventType: system.DigitalPinEventFallingEdge}, + }, + wants: []int64{9}, + }, + "event_rising_before": { + calls: []eventCall{ + {timeStamp: 1 * time.Microsecond, eventType: system.DigitalPinEventRisingEdge}, + {timeStamp: 5 * time.Microsecond, eventType: system.DigitalPinEventRisingEdge}, + {timeStamp: 10 * time.Microsecond, eventType: system.DigitalPinEventFallingEdge}, + }, + wants: []int64{5}, + }, + "event_rising_after": { + calls: []eventCall{ + {timeStamp: 1 * time.Microsecond, eventType: system.DigitalPinEventRisingEdge}, + {timeStamp: 10 * time.Microsecond, eventType: system.DigitalPinEventFallingEdge}, + {timeStamp: 12 * time.Microsecond, eventType: system.DigitalPinEventRisingEdge}, + }, + wants: []int64{9}, + }, + "event_multiple": { + calls: []eventCall{ + {timeStamp: 1 * time.Microsecond, eventType: system.DigitalPinEventRisingEdge}, + {timeStamp: 10 * time.Microsecond, eventType: system.DigitalPinEventFallingEdge}, + {timeStamp: 11 * time.Microsecond, eventType: system.DigitalPinEventRisingEdge}, + {timeStamp: 13 * time.Microsecond, eventType: system.DigitalPinEventFallingEdge}, + }, + wants: []int64{9, 2}, + }, + } + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + // arrange + d := HCSR04Driver{delayMicroSecChan: make(chan int64, len(tc.wants))} + // act + eh := d.createEventHandler() + for _, call := range tc.calls { + eh(0, call.timeStamp, call.eventType, 0, 0) + } + // assert + for _, want := range tc.wants { + got := <-d.delayMicroSecChan + assert.Equal(t, want, got) + } + }) + } +} diff --git a/drivers/gpio/hd44780_driver_test.go b/drivers/gpio/hd44780_driver_test.go index 5a4ccadb7..81985d98f 100644 --- a/drivers/gpio/hd44780_driver_test.go +++ b/drivers/gpio/hd44780_driver_test.go @@ -5,8 +5,9 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" + "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*HD44780Driver)(nil) @@ -60,23 +61,23 @@ func TestHD44780Driver(t *testing.T) { func TestHD44780DriverHalt(t *testing.T) { d := initTestHD44780Driver() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestHD44780DriverDefaultName(t *testing.T) { d, _ := initTestHD44780Driver4BitModeWithStubbedAdaptor() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "HD44780Driver"), true) + assert.True(t, strings.HasPrefix(d.Name(), "HD44780Driver")) } func TestHD44780DriverSetName(t *testing.T) { d, _ := initTestHD44780Driver4BitModeWithStubbedAdaptor() d.SetName("my driver") - gobottest.Assert(t, d.Name(), "my driver") + assert.Equal(t, "my driver", d.Name()) } func TestHD44780DriverStart(t *testing.T) { d, _ := initTestHD44780Driver4BitModeWithStubbedAdaptor() - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestHD44780DriverStartError(t *testing.T) { @@ -92,7 +93,7 @@ func TestHD44780DriverStartError(t *testing.T) { D7: "", } d = NewHD44780Driver(a, 2, 16, HD44780_4BITMODE, "13", "15", pins) - gobottest.Assert(t, d.Start(), errors.New("Initialization error")) + assert.ErrorContains(t, d.Start(), "Initialization error") pins = HD44780DataPin{ D0: "31", @@ -105,7 +106,7 @@ func TestHD44780DriverStartError(t *testing.T) { D7: "", } d = NewHD44780Driver(a, 2, 16, HD44780_8BITMODE, "13", "15", pins) - gobottest.Assert(t, d.Start(), errors.New("Initialization error")) + assert.ErrorContains(t, d.Start(), "Initialization error") } func TestHD44780DriverWrite(t *testing.T) { @@ -113,11 +114,11 @@ func TestHD44780DriverWrite(t *testing.T) { d, _ = initTestHD44780Driver4BitModeWithStubbedAdaptor() _ = d.Start() - gobottest.Assert(t, d.Write("hello gobot"), nil) + assert.NoError(t, d.Write("hello gobot")) d, _ = initTestHD44780Driver8BitModeWithStubbedAdaptor() _ = d.Start() - gobottest.Assert(t, d.Write("hello gobot"), nil) + assert.NoError(t, d.Write("hello gobot")) } func TestHD44780DriverWriteError(t *testing.T) { @@ -125,111 +126,112 @@ func TestHD44780DriverWriteError(t *testing.T) { var a *gpioTestAdaptor d, a = initTestHD44780Driver4BitModeWithStubbedAdaptor() - a.testAdaptorDigitalWrite = func(string, byte) (err error) { + a.digitalWriteFunc = func(string, byte) (err error) { return errors.New("write error") } _ = d.Start() - gobottest.Assert(t, d.Write("hello gobot"), errors.New("write error")) + assert.ErrorContains(t, d.Write("hello gobot"), "write error") d, a = initTestHD44780Driver8BitModeWithStubbedAdaptor() - a.testAdaptorDigitalWrite = func(string, byte) (err error) { + a.digitalWriteFunc = func(string, byte) (err error) { return errors.New("write error") } _ = d.Start() - gobottest.Assert(t, d.Write("hello gobot"), errors.New("write error")) + assert.ErrorContains(t, d.Write("hello gobot"), "write error") } func TestHD44780DriverClear(t *testing.T) { d := initTestHD44780Driver() - gobottest.Assert(t, d.Clear(), nil) + assert.NoError(t, d.Clear()) } func TestHD44780DriverHome(t *testing.T) { d := initTestHD44780Driver() - gobottest.Assert(t, d.Home(), nil) + assert.NoError(t, d.Home()) } func TestHD44780DriverSetCursor(t *testing.T) { d := initTestHD44780Driver() - gobottest.Assert(t, d.SetCursor(0, 3), nil) + assert.NoError(t, d.SetCursor(0, 3)) } func TestHD44780DriverSetCursorInvalid(t *testing.T) { d := initTestHD44780Driver() - gobottest.Assert(t, d.SetCursor(-1, 3), errors.New("Invalid position value (-1, 3), range (1, 15)")) - gobottest.Assert(t, d.SetCursor(2, 3), errors.New("Invalid position value (2, 3), range (1, 15)")) - gobottest.Assert(t, d.SetCursor(0, -1), errors.New("Invalid position value (0, -1), range (1, 15)")) - gobottest.Assert(t, d.SetCursor(0, 16), errors.New("Invalid position value (0, 16), range (1, 15)")) + + assert.ErrorContains(t, d.SetCursor(-1, 3), "Invalid position value (-1, 3), range (1, 15)") + assert.ErrorContains(t, d.SetCursor(2, 3), "Invalid position value (2, 3), range (1, 15)") + assert.ErrorContains(t, d.SetCursor(0, -1), "Invalid position value (0, -1), range (1, 15)") + assert.ErrorContains(t, d.SetCursor(0, 16), "Invalid position value (0, 16), range (1, 15)") } func TestHD44780DriverDisplayOn(t *testing.T) { d := initTestHD44780Driver() - gobottest.Assert(t, d.Display(true), nil) + assert.NoError(t, d.Display(true)) } func TestHD44780DriverDisplayOff(t *testing.T) { d := initTestHD44780Driver() - gobottest.Assert(t, d.Display(false), nil) + assert.NoError(t, d.Display(false)) } func TestHD44780DriverCursorOn(t *testing.T) { d := initTestHD44780Driver() - gobottest.Assert(t, d.Cursor(true), nil) + assert.NoError(t, d.Cursor(true)) } func TestHD44780DriverCursorOff(t *testing.T) { d := initTestHD44780Driver() - gobottest.Assert(t, d.Cursor(false), nil) + assert.NoError(t, d.Cursor(false)) } func TestHD44780DriverBlinkOn(t *testing.T) { d := initTestHD44780Driver() - gobottest.Assert(t, d.Blink(true), nil) + assert.NoError(t, d.Blink(true)) } func TestHD44780DriverBlinkOff(t *testing.T) { d := initTestHD44780Driver() - gobottest.Assert(t, d.Blink(false), nil) + assert.NoError(t, d.Blink(false)) } func TestHD44780DriverScrollLeft(t *testing.T) { d := initTestHD44780Driver() - gobottest.Assert(t, d.ScrollLeft(), nil) + assert.NoError(t, d.ScrollLeft()) } func TestHD44780DriverScrollRight(t *testing.T) { d := initTestHD44780Driver() - gobottest.Assert(t, d.ScrollRight(), nil) + assert.NoError(t, d.ScrollRight()) } func TestHD44780DriverLeftToRight(t *testing.T) { d := initTestHD44780Driver() - gobottest.Assert(t, d.LeftToRight(), nil) + assert.NoError(t, d.LeftToRight()) } func TestHD44780DriverRightToLeft(t *testing.T) { d := initTestHD44780Driver() - gobottest.Assert(t, d.RightToLeft(), nil) + assert.NoError(t, d.RightToLeft()) } func TestHD44780DriverSendCommand(t *testing.T) { d := initTestHD44780Driver() - gobottest.Assert(t, d.SendCommand(0x33), nil) + assert.NoError(t, d.SendCommand(0x33)) } func TestHD44780DriverWriteChar(t *testing.T) { d := initTestHD44780Driver() - gobottest.Assert(t, d.WriteChar(0x41), nil) + assert.NoError(t, d.WriteChar(0x41)) } func TestHD44780DriverCreateChar(t *testing.T) { d := initTestHD44780Driver() charMap := [8]byte{1, 2, 3, 4, 5, 6, 7, 8} - gobottest.Assert(t, d.CreateChar(0, charMap), nil) + assert.NoError(t, d.CreateChar(0, charMap)) } func TestHD44780DriverCreateCharError(t *testing.T) { d := initTestHD44780Driver() charMap := [8]byte{1, 2, 3, 4, 5, 6, 7, 8} - gobottest.Assert(t, d.CreateChar(8, charMap), errors.New("can't set a custom character at a position greater than 7")) + assert.ErrorContains(t, d.CreateChar(8, charMap), "can't set a custom character at a position greater than 7") } diff --git a/drivers/gpio/helpers_test.go b/drivers/gpio/helpers_test.go index 959ba7c65..41c051159 100644 --- a/drivers/gpio/helpers_test.go +++ b/drivers/gpio/helpers_test.go @@ -1,6 +1,11 @@ package gpio -import "sync" +import ( + "fmt" + "sync" + + "gobot.io/x/gobot/v2" +) type gpioTestBareAdaptor struct{} @@ -9,91 +14,114 @@ func (t *gpioTestBareAdaptor) Finalize() (err error) { return } func (t *gpioTestBareAdaptor) Name() string { return "" } func (t *gpioTestBareAdaptor) SetName(n string) {} -type gpioTestAdaptor struct { - name string - port string - mtx sync.Mutex - testAdaptorDigitalWrite func(pin string, val byte) (err error) - testAdaptorServoWrite func(pin string, val byte) (err error) - testAdaptorPwmWrite func(pin string, val byte) (err error) - testAdaptorAnalogRead func(ping string) (val int, err error) - testAdaptorDigitalRead func(ping string) (val int, err error) +type digitalPinMock struct { + writeFunc func(val int) (err error) } -func (t *gpioTestAdaptor) TestAdaptorDigitalWrite(f func(pin string, val byte) (err error)) { - t.mtx.Lock() - defer t.mtx.Unlock() - t.testAdaptorDigitalWrite = f -} -func (t *gpioTestAdaptor) TestAdaptorServoWrite(f func(pin string, val byte) (err error)) { - t.mtx.Lock() - defer t.mtx.Unlock() - t.testAdaptorServoWrite = f -} -func (t *gpioTestAdaptor) TestAdaptorPwmWrite(f func(pin string, val byte) (err error)) { - t.mtx.Lock() - defer t.mtx.Unlock() - t.testAdaptorPwmWrite = f +type gpioTestAdaptor struct { + name string + pinMap map[string]gobot.DigitalPinner + port string + mtx sync.Mutex + digitalReadFunc func(ping string) (val int, err error) + digitalWriteFunc func(pin string, val byte) (err error) + pwmWriteFunc func(pin string, val byte) (err error) + servoWriteFunc func(pin string, val byte) (err error) } -func (t *gpioTestAdaptor) TestAdaptorAnalogRead(f func(pin string) (val int, err error)) { - t.mtx.Lock() - defer t.mtx.Unlock() - t.testAdaptorAnalogRead = f + +func newGpioTestAdaptor() *gpioTestAdaptor { + t := gpioTestAdaptor{ + name: "gpio_test_adaptor", + pinMap: make(map[string]gobot.DigitalPinner), + port: "/dev/null", + digitalWriteFunc: func(pin string, val byte) (err error) { + return nil + }, + servoWriteFunc: func(pin string, val byte) (err error) { + return nil + }, + pwmWriteFunc: func(pin string, val byte) (err error) { + return nil + }, + digitalReadFunc: func(pin string) (val int, err error) { + return 1, nil + }, + } + + return &t } -func (t *gpioTestAdaptor) TestAdaptorDigitalRead(f func(pin string) (val int, err error)) { + +// DigitalRead capabilities (interface DigitalReader) +func (t *gpioTestAdaptor) DigitalRead(pin string) (val int, err error) { t.mtx.Lock() defer t.mtx.Unlock() - t.testAdaptorDigitalRead = f + return t.digitalReadFunc(pin) } -func (t *gpioTestAdaptor) ServoWrite(pin string, val byte) (err error) { +// DigitalWrite capabilities (interface DigitalWriter) +func (t *gpioTestAdaptor) DigitalWrite(pin string, val byte) (err error) { t.mtx.Lock() defer t.mtx.Unlock() - return t.testAdaptorServoWrite(pin, val) + return t.digitalWriteFunc(pin, val) } + +// PwmWrite capabilities (interface PwmWriter) func (t *gpioTestAdaptor) PwmWrite(pin string, val byte) (err error) { t.mtx.Lock() defer t.mtx.Unlock() - return t.testAdaptorPwmWrite(pin, val) -} -func (t *gpioTestAdaptor) AnalogRead(pin string) (val int, err error) { - t.mtx.Lock() - defer t.mtx.Unlock() - return t.testAdaptorAnalogRead(pin) -} -func (t *gpioTestAdaptor) DigitalRead(pin string) (val int, err error) { - t.mtx.Lock() - defer t.mtx.Unlock() - return t.testAdaptorDigitalRead(pin) + return t.pwmWriteFunc(pin, val) } -func (t *gpioTestAdaptor) DigitalWrite(pin string, val byte) (err error) { + +// ServoWrite capabilities (interface ServoWriter) +func (t *gpioTestAdaptor) ServoWrite(pin string, val byte) (err error) { t.mtx.Lock() defer t.mtx.Unlock() - return t.testAdaptorDigitalWrite(pin, val) + return t.servoWriteFunc(pin, val) } + func (t *gpioTestAdaptor) Connect() (err error) { return } func (t *gpioTestAdaptor) Finalize() (err error) { return } func (t *gpioTestAdaptor) Name() string { return t.name } func (t *gpioTestAdaptor) SetName(n string) { t.name = n } func (t *gpioTestAdaptor) Port() string { return t.port } -func newGpioTestAdaptor() *gpioTestAdaptor { - return &gpioTestAdaptor{ - port: "/dev/null", - testAdaptorDigitalWrite: func(pin string, val byte) (err error) { - return nil - }, - testAdaptorServoWrite: func(pin string, val byte) (err error) { - return nil - }, - testAdaptorPwmWrite: func(pin string, val byte) (err error) { - return nil - }, - testAdaptorAnalogRead: func(pin string) (val int, err error) { - return 99, nil - }, - testAdaptorDigitalRead: func(pin string) (val int, err error) { - return 1, nil - }, +// DigitalPin (interface DigitalPinnerProvider) return a pin object +func (t *gpioTestAdaptor) DigitalPin(id string) (gobot.DigitalPinner, error) { + if pin, ok := t.pinMap[id]; ok { + return pin, nil + } + return nil, fmt.Errorf("pin '%s' not found in '%s'", id, t.name) +} + +// ApplyOptions (interface DigitalPinOptionApplier by DigitalPinner) apply all given options to the pin immediately +func (d *digitalPinMock) ApplyOptions(options ...func(gobot.DigitalPinOptioner) bool) error { + return nil +} + +// Export (interface DigitalPinner) exports the pin for use by the adaptor +func (d *digitalPinMock) Export() error { + return nil +} + +// Unexport (interface DigitalPinner) releases the pin from the adaptor, so it is free for the operating system +func (d *digitalPinMock) Unexport() error { + return nil +} + +// Read (interface DigitalPinner) reads the current value of the pin +func (d *digitalPinMock) Read() (n int, err error) { + return 0, err +} + +// Write (interface DigitalPinner) writes to the pin +func (d *digitalPinMock) Write(b int) error { + return d.writeFunc(b) +} + +func (t *gpioTestAdaptor) addDigitalPin(id string) *digitalPinMock { + dpm := &digitalPinMock{ + writeFunc: func(val int) (err error) { return nil }, } + t.pinMap[id] = dpm + return dpm } diff --git a/drivers/gpio/led_driver_test.go b/drivers/gpio/led_driver_test.go index cd6fc57f0..38d40bc76 100644 --- a/drivers/gpio/led_driver_test.go +++ b/drivers/gpio/led_driver_test.go @@ -5,18 +5,18 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*LedDriver)(nil) func initTestLedDriver() *LedDriver { a := newGpioTestAdaptor() - a.testAdaptorDigitalWrite = func(string, byte) (err error) { + a.digitalWriteFunc = func(string, byte) (err error) { return nil } - a.testAdaptorPwmWrite = func(string, byte) (err error) { + a.pwmWriteFunc = func(string, byte) (err error) { return nil } return NewLedDriver(a, "1") @@ -27,68 +27,67 @@ func TestLedDriver(t *testing.T) { a := newGpioTestAdaptor() d := NewLedDriver(a, "1") - gobottest.Assert(t, d.Pin(), "1") - gobottest.Refute(t, d.Connection(), nil) + assert.Equal(t, "1", d.Pin()) + assert.NotNil(t, d.Connection()) - a.testAdaptorDigitalWrite = func(string, byte) (err error) { + a.digitalWriteFunc = func(string, byte) (err error) { return errors.New("write error") } - a.testAdaptorPwmWrite = func(string, byte) (err error) { + a.pwmWriteFunc = func(string, byte) (err error) { return errors.New("pwm error") } err = d.Command("Toggle")(nil) - gobottest.Assert(t, err.(error), errors.New("write error")) + assert.ErrorContains(t, err.(error), "write error") err = d.Command("On")(nil) - gobottest.Assert(t, err.(error), errors.New("write error")) + assert.ErrorContains(t, err.(error), "write error") err = d.Command("Off")(nil) - gobottest.Assert(t, err.(error), errors.New("write error")) + assert.ErrorContains(t, err.(error), "write error") err = d.Command("Brightness")(map[string]interface{}{"level": 100.0}) - gobottest.Assert(t, err.(error), errors.New("pwm error")) - + assert.ErrorContains(t, err.(error), "pwm error") } func TestLedDriverStart(t *testing.T) { d := initTestLedDriver() - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestLedDriverHalt(t *testing.T) { d := initTestLedDriver() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestLedDriverToggle(t *testing.T) { d := initTestLedDriver() _ = d.Off() _ = d.Toggle() - gobottest.Assert(t, d.State(), true) + assert.True(t, d.State()) _ = d.Toggle() - gobottest.Assert(t, d.State(), false) + assert.False(t, d.State()) } func TestLedDriverBrightness(t *testing.T) { a := newGpioTestAdaptor() d := NewLedDriver(a, "1") - a.testAdaptorPwmWrite = func(string, byte) (err error) { + a.pwmWriteFunc = func(string, byte) (err error) { err = errors.New("pwm error") return } - gobottest.Assert(t, d.Brightness(150), errors.New("pwm error")) + assert.ErrorContains(t, d.Brightness(150), "pwm error") } func TestLEDDriverDefaultName(t *testing.T) { a := newGpioTestAdaptor() d := NewLedDriver(a, "1") - gobottest.Assert(t, strings.HasPrefix(d.Name(), "LED"), true) + assert.True(t, strings.HasPrefix(d.Name(), "LED")) } func TestLEDDriverSetName(t *testing.T) { a := newGpioTestAdaptor() d := NewLedDriver(a, "1") d.SetName("mybot") - gobottest.Assert(t, d.Name(), "mybot") + assert.Equal(t, "mybot", d.Name()) } diff --git a/drivers/gpio/makey_button_driver_test.go b/drivers/gpio/makey_button_driver_test.go index 0fb54c144..996e6a39a 100644 --- a/drivers/gpio/makey_button_driver_test.go +++ b/drivers/gpio/makey_button_driver_test.go @@ -5,8 +5,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*MakeyButtonDriver)(nil) @@ -24,7 +24,7 @@ func TestMakeyButtonDriverHalt(t *testing.T) { <-d.halt close(done) }() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) select { case <-done: case <-time.After(makeyTestDelay * time.Millisecond): @@ -34,12 +34,12 @@ func TestMakeyButtonDriverHalt(t *testing.T) { func TestMakeyButtonDriver(t *testing.T) { d := initTestMakeyButtonDriver() - gobottest.Assert(t, d.Pin(), "1") - gobottest.Refute(t, d.Connection(), nil) - gobottest.Assert(t, d.interval, 10*time.Millisecond) + assert.Equal(t, "1", d.Pin()) + assert.NotNil(t, d.Connection()) + assert.Equal(t, 10*time.Millisecond, d.interval) d = NewMakeyButtonDriver(newGpioTestAdaptor(), "1", 30*time.Second) - gobottest.Assert(t, d.interval, 30*time.Second) + assert.Equal(t, 30*time.Second, d.interval) } func TestMakeyButtonDriverStart(t *testing.T) { @@ -47,17 +47,17 @@ func TestMakeyButtonDriverStart(t *testing.T) { a := newGpioTestAdaptor() d := NewMakeyButtonDriver(a, "1") - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) _ = d.Once(ButtonPush, func(data interface{}) { - gobottest.Assert(t, d.Active, true) + assert.True(t, d.Active) sem <- true }) - a.TestAdaptorDigitalRead(func(string) (val int, err error) { + a.digitalReadFunc = func(string) (val int, err error) { val = 0 return - }) + } select { case <-sem: @@ -66,14 +66,14 @@ func TestMakeyButtonDriverStart(t *testing.T) { } _ = d.Once(ButtonRelease, func(data interface{}) { - gobottest.Assert(t, d.Active, false) + assert.False(t, d.Active) sem <- true }) - a.TestAdaptorDigitalRead(func(string) (val int, err error) { + a.digitalReadFunc = func(string) (val int, err error) { val = 1 return - }) + } select { case <-sem: @@ -82,14 +82,14 @@ func TestMakeyButtonDriverStart(t *testing.T) { } _ = d.Once(Error, func(data interface{}) { - gobottest.Assert(t, data.(error).Error(), "digital read error") + assert.Equal(t, "digital read error", data.(error).Error()) sem <- true }) - a.TestAdaptorDigitalRead(func(string) (val int, err error) { + a.digitalReadFunc = func(string) (val int, err error) { err = errors.New("digital read error") return - }) + } select { case <-sem: @@ -102,10 +102,10 @@ func TestMakeyButtonDriverStart(t *testing.T) { sem <- true }) - a.TestAdaptorDigitalRead(func(string) (val int, err error) { + a.digitalReadFunc = func(string) (val int, err error) { val = 1 return - }) + } d.halt <- true diff --git a/drivers/gpio/max7219_driver_test.go b/drivers/gpio/max7219_driver_test.go index dda37438b..9fab6bd22 100644 --- a/drivers/gpio/max7219_driver_test.go +++ b/drivers/gpio/max7219_driver_test.go @@ -4,8 +4,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*MAX7219Driver)(nil) @@ -32,21 +32,21 @@ func TestMAX7219Driver(t *testing.T) { func TestMAX7219DriverStart(t *testing.T) { d := initTestMAX7219Driver() - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestMAX7219DriverHalt(t *testing.T) { d := initTestMAX7219Driver() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestMAX7219DriverDefaultName(t *testing.T) { d := initTestMAX7219Driver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "MAX7219Driver"), true) + assert.True(t, strings.HasPrefix(d.Name(), "MAX7219Driver")) } func TestMAX7219DriverSetName(t *testing.T) { d := initTestMAX7219Driver() d.SetName("mybot") - gobottest.Assert(t, d.Name(), "mybot") + assert.Equal(t, "mybot", d.Name()) } diff --git a/drivers/gpio/motor_driver_test.go b/drivers/gpio/motor_driver_test.go index aa382fec3..6ec1c9142 100644 --- a/drivers/gpio/motor_driver_test.go +++ b/drivers/gpio/motor_driver_test.go @@ -4,8 +4,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*MotorDriver)(nil) @@ -16,64 +16,64 @@ func initTestMotorDriver() *MotorDriver { func TestMotorDriver(t *testing.T) { d := NewMotorDriver(newGpioTestAdaptor(), "1") - gobottest.Refute(t, d.Connection(), nil) - + assert.NotNil(t, d.Connection()) } + func TestMotorDriverStart(t *testing.T) { d := initTestMotorDriver() - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestMotorDriverHalt(t *testing.T) { d := initTestMotorDriver() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestMotorDriverIsOn(t *testing.T) { d := initTestMotorDriver() d.CurrentMode = "digital" d.CurrentState = 1 - gobottest.Assert(t, d.IsOn(), true) + assert.True(t, d.IsOn()) d.CurrentMode = "analog" d.CurrentSpeed = 100 - gobottest.Assert(t, d.IsOn(), true) + assert.True(t, d.IsOn()) } func TestMotorDriverIsOff(t *testing.T) { d := initTestMotorDriver() _ = d.Off() - gobottest.Assert(t, d.IsOff(), true) + assert.True(t, d.IsOff()) } func TestMotorDriverOn(t *testing.T) { d := initTestMotorDriver() d.CurrentMode = "digital" _ = d.On() - gobottest.Assert(t, d.CurrentState, uint8(1)) + assert.Equal(t, uint8(1), d.CurrentState) d.CurrentMode = "analog" d.CurrentSpeed = 0 _ = d.On() - gobottest.Assert(t, d.CurrentSpeed, uint8(255)) + assert.Equal(t, uint8(255), d.CurrentSpeed) } func TestMotorDriverOff(t *testing.T) { d := initTestMotorDriver() d.CurrentMode = "digital" _ = d.Off() - gobottest.Assert(t, d.CurrentState, uint8(0)) + assert.Equal(t, uint8(0), d.CurrentState) d.CurrentMode = "analog" d.CurrentSpeed = 100 _ = d.Off() - gobottest.Assert(t, d.CurrentSpeed, uint8(0)) + assert.Equal(t, uint8(0), d.CurrentSpeed) } func TestMotorDriverToggle(t *testing.T) { d := initTestMotorDriver() _ = d.Off() _ = d.Toggle() - gobottest.Assert(t, d.IsOn(), true) + assert.True(t, d.IsOn()) _ = d.Toggle() - gobottest.Assert(t, d.IsOn(), false) + assert.False(t, d.IsOn()) } func TestMotorDriverMin(t *testing.T) { @@ -94,15 +94,15 @@ func TestMotorDriverSpeed(t *testing.T) { func TestMotorDriverForward(t *testing.T) { d := initTestMotorDriver() _ = d.Forward(100) - gobottest.Assert(t, d.CurrentSpeed, uint8(100)) - gobottest.Assert(t, d.CurrentDirection, "forward") + assert.Equal(t, uint8(100), d.CurrentSpeed) + assert.Equal(t, "forward", d.CurrentDirection) } func TestMotorDriverBackward(t *testing.T) { d := initTestMotorDriver() _ = d.Backward(100) - gobottest.Assert(t, d.CurrentSpeed, uint8(100)) - gobottest.Assert(t, d.CurrentDirection, "backward") + assert.Equal(t, uint8(100), d.CurrentSpeed) + assert.Equal(t, "backward", d.CurrentDirection) } func TestMotorDriverDirection(t *testing.T) { @@ -121,18 +121,18 @@ func TestMotorDriverDigital(t *testing.T) { d.BackwardPin = "3" _ = d.On() - gobottest.Assert(t, d.CurrentState, uint8(1)) + assert.Equal(t, uint8(1), d.CurrentState) _ = d.Off() - gobottest.Assert(t, d.CurrentState, uint8(0)) + assert.Equal(t, uint8(0), d.CurrentState) } func TestMotorDriverDefaultName(t *testing.T) { d := initTestMotorDriver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "Motor"), true) + assert.True(t, strings.HasPrefix(d.Name(), "Motor")) } func TestMotorDriverSetName(t *testing.T) { d := initTestMotorDriver() d.SetName("mybot") - gobottest.Assert(t, d.Name(), "mybot") + assert.Equal(t, "mybot", d.Name()) } diff --git a/drivers/gpio/pir_motion_driver_test.go b/drivers/gpio/pir_motion_driver_test.go index 6cfc755b1..79ab0d710 100644 --- a/drivers/gpio/pir_motion_driver_test.go +++ b/drivers/gpio/pir_motion_driver_test.go @@ -6,8 +6,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*PIRMotionDriver)(nil) @@ -23,15 +23,15 @@ func TestPIRMotionDriverHalt(t *testing.T) { go func() { <-d.halt }() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestPIRMotionDriver(t *testing.T) { d := NewPIRMotionDriver(newGpioTestAdaptor(), "1") - gobottest.Refute(t, d.Connection(), nil) + assert.NotNil(t, d.Connection()) d = NewPIRMotionDriver(newGpioTestAdaptor(), "1", 30*time.Second) - gobottest.Assert(t, d.interval, 30*time.Second) + assert.Equal(t, 30*time.Second, d.interval) } func TestPIRMotionDriverStart(t *testing.T) { @@ -39,17 +39,17 @@ func TestPIRMotionDriverStart(t *testing.T) { a := newGpioTestAdaptor() d := NewPIRMotionDriver(a, "1") - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) _ = d.Once(MotionDetected, func(data interface{}) { - gobottest.Assert(t, d.Active, true) + assert.True(t, d.Active) sem <- true }) - a.TestAdaptorDigitalRead(func(string) (val int, err error) { + a.digitalReadFunc = func(string) (val int, err error) { val = 1 return - }) + } select { case <-sem: @@ -58,14 +58,14 @@ func TestPIRMotionDriverStart(t *testing.T) { } _ = d.Once(MotionStopped, func(data interface{}) { - gobottest.Assert(t, d.Active, false) + assert.False(t, d.Active) sem <- true }) - a.TestAdaptorDigitalRead(func(string) (val int, err error) { + a.digitalReadFunc = func(string) (val int, err error) { val = 0 return - }) + } select { case <-sem: @@ -77,10 +77,10 @@ func TestPIRMotionDriverStart(t *testing.T) { sem <- true }) - a.TestAdaptorDigitalRead(func(string) (val int, err error) { + a.digitalReadFunc = func(string) (val int, err error) { err = errors.New("digital read error") return - }) + } select { case <-sem: @@ -91,11 +91,11 @@ func TestPIRMotionDriverStart(t *testing.T) { func TestPIRDriverDefaultName(t *testing.T) { d := initTestPIRMotionDriver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "PIR"), true) + assert.True(t, strings.HasPrefix(d.Name(), "PIR")) } func TestPIRDriverSetName(t *testing.T) { d := initTestPIRMotionDriver() d.SetName("mybot") - gobottest.Assert(t, d.Name(), "mybot") + assert.Equal(t, "mybot", d.Name()) } diff --git a/drivers/gpio/relay_driver_test.go b/drivers/gpio/relay_driver_test.go index 12160357a..340965d72 100644 --- a/drivers/gpio/relay_driver_test.go +++ b/drivers/gpio/relay_driver_test.go @@ -4,8 +4,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*RelayDriver)(nil) @@ -15,10 +15,10 @@ func (l *RelayDriver) High() bool { return l.high } func initTestRelayDriver() (*RelayDriver, *gpioTestAdaptor) { a := newGpioTestAdaptor() - a.testAdaptorDigitalWrite = func(string, byte) (err error) { + a.digitalWriteFunc = func(string, byte) (err error) { return nil } - a.testAdaptorPwmWrite = func(string, byte) (err error) { + a.pwmWriteFunc = func(string, byte) (err error) { return nil } return NewRelayDriver(a, "1"), a @@ -26,107 +26,107 @@ func initTestRelayDriver() (*RelayDriver, *gpioTestAdaptor) { func TestRelayDriverDefaultName(t *testing.T) { g, _ := initTestRelayDriver() - gobottest.Refute(t, g.Connection(), nil) - gobottest.Assert(t, strings.HasPrefix(g.Name(), "Relay"), true) + assert.NotNil(t, g.Connection()) + assert.True(t, strings.HasPrefix(g.Name(), "Relay")) } func TestRelayDriverSetName(t *testing.T) { g, _ := initTestRelayDriver() g.SetName("mybot") - gobottest.Assert(t, g.Name(), "mybot") + assert.Equal(t, "mybot", g.Name()) } func TestRelayDriverStart(t *testing.T) { d, _ := initTestRelayDriver() - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestRelayDriverHalt(t *testing.T) { d, _ := initTestRelayDriver() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestRelayDriverToggle(t *testing.T) { d, a := initTestRelayDriver() var lastVal byte - a.TestAdaptorDigitalWrite(func(pin string, val byte) error { + a.digitalWriteFunc = func(pin string, val byte) error { lastVal = val return nil - }) + } _ = d.Off() - gobottest.Assert(t, d.State(), false) - gobottest.Assert(t, lastVal, byte(0)) + assert.False(t, d.State()) + assert.Equal(t, byte(0), lastVal) _ = d.Toggle() - gobottest.Assert(t, d.State(), true) - gobottest.Assert(t, lastVal, byte(1)) + assert.True(t, d.State()) + assert.Equal(t, byte(1), lastVal) _ = d.Toggle() - gobottest.Assert(t, d.State(), false) - gobottest.Assert(t, lastVal, byte(0)) + assert.False(t, d.State()) + assert.Equal(t, byte(0), lastVal) } func TestRelayDriverToggleInverted(t *testing.T) { d, a := initTestRelayDriver() var lastVal byte - a.TestAdaptorDigitalWrite(func(pin string, val byte) error { + a.digitalWriteFunc = func(pin string, val byte) error { lastVal = val return nil - }) + } d.Inverted = true _ = d.Off() - gobottest.Assert(t, d.State(), false) - gobottest.Assert(t, lastVal, byte(1)) + assert.False(t, d.State()) + assert.Equal(t, byte(1), lastVal) _ = d.Toggle() - gobottest.Assert(t, d.State(), true) - gobottest.Assert(t, lastVal, byte(0)) + assert.True(t, d.State()) + assert.Equal(t, byte(0), lastVal) _ = d.Toggle() - gobottest.Assert(t, d.State(), false) - gobottest.Assert(t, lastVal, byte(1)) + assert.False(t, d.State()) + assert.Equal(t, byte(1), lastVal) } func TestRelayDriverCommands(t *testing.T) { d, a := initTestRelayDriver() var lastVal byte - a.TestAdaptorDigitalWrite(func(pin string, val byte) error { + a.digitalWriteFunc = func(pin string, val byte) error { lastVal = val return nil - }) + } - gobottest.Assert(t, d.Command("Off")(nil), nil) - gobottest.Assert(t, d.State(), false) - gobottest.Assert(t, lastVal, byte(0)) + assert.Nil(t, d.Command("Off")(nil)) + assert.False(t, d.State()) + assert.Equal(t, byte(0), lastVal) - gobottest.Assert(t, d.Command("On")(nil), nil) - gobottest.Assert(t, d.State(), true) - gobottest.Assert(t, lastVal, byte(1)) + assert.Nil(t, d.Command("On")(nil)) + assert.True(t, d.State()) + assert.Equal(t, byte(1), lastVal) - gobottest.Assert(t, d.Command("Toggle")(nil), nil) - gobottest.Assert(t, d.State(), false) - gobottest.Assert(t, lastVal, byte(0)) + assert.Nil(t, d.Command("Toggle")(nil)) + assert.False(t, d.State()) + assert.Equal(t, byte(0), lastVal) } func TestRelayDriverCommandsInverted(t *testing.T) { d, a := initTestRelayDriver() var lastVal byte - a.TestAdaptorDigitalWrite(func(pin string, val byte) error { + a.digitalWriteFunc = func(pin string, val byte) error { lastVal = val return nil - }) + } d.Inverted = true - gobottest.Assert(t, d.Command("Off")(nil), nil) - gobottest.Assert(t, d.High(), true) - gobottest.Assert(t, d.State(), false) - gobottest.Assert(t, lastVal, byte(1)) + assert.Nil(t, d.Command("Off")(nil)) + assert.True(t, d.High()) + assert.False(t, d.State()) + assert.Equal(t, byte(1), lastVal) - gobottest.Assert(t, d.Command("On")(nil), nil) - gobottest.Assert(t, d.High(), false) - gobottest.Assert(t, d.State(), true) - gobottest.Assert(t, lastVal, byte(0)) + assert.Nil(t, d.Command("On")(nil)) + assert.False(t, d.High()) + assert.True(t, d.State()) + assert.Equal(t, byte(0), lastVal) - gobottest.Assert(t, d.Command("Toggle")(nil), nil) - gobottest.Assert(t, d.High(), true) - gobottest.Assert(t, d.State(), false) - gobottest.Assert(t, lastVal, byte(1)) + assert.Nil(t, d.Command("Toggle")(nil)) + assert.True(t, d.High()) + assert.False(t, d.State()) + assert.Equal(t, byte(1), lastVal) } diff --git a/drivers/gpio/rgb_led_driver_test.go b/drivers/gpio/rgb_led_driver_test.go index 2e9ffc9ca..818e2490a 100644 --- a/drivers/gpio/rgb_led_driver_test.go +++ b/drivers/gpio/rgb_led_driver_test.go @@ -5,18 +5,18 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*RgbLedDriver)(nil) func initTestRgbLedDriver() *RgbLedDriver { a := newGpioTestAdaptor() - a.testAdaptorDigitalWrite = func(string, byte) (err error) { + a.digitalWriteFunc = func(string, byte) (err error) { return nil } - a.testAdaptorPwmWrite = func(string, byte) (err error) { + a.pwmWriteFunc = func(string, byte) (err error) { return nil } return NewRgbLedDriver(a, "1", "2", "3") @@ -28,73 +28,73 @@ func TestRgbLedDriver(t *testing.T) { a := newGpioTestAdaptor() d := NewRgbLedDriver(a, "1", "2", "3") - gobottest.Assert(t, d.Pin(), "r=1, g=2, b=3") - gobottest.Assert(t, d.RedPin(), "1") - gobottest.Assert(t, d.GreenPin(), "2") - gobottest.Assert(t, d.BluePin(), "3") - gobottest.Refute(t, d.Connection(), nil) + assert.Equal(t, "r=1, g=2, b=3", d.Pin()) + assert.Equal(t, "1", d.RedPin()) + assert.Equal(t, "2", d.GreenPin()) + assert.Equal(t, "3", d.BluePin()) + assert.NotNil(t, d.Connection()) - a.testAdaptorDigitalWrite = func(string, byte) (err error) { + a.digitalWriteFunc = func(string, byte) (err error) { return errors.New("write error") } - a.testAdaptorPwmWrite = func(string, byte) (err error) { + a.pwmWriteFunc = func(string, byte) (err error) { return errors.New("pwm error") } err = d.Command("Toggle")(nil) - gobottest.Assert(t, err.(error), errors.New("pwm error")) + assert.ErrorContains(t, err.(error), "pwm error") err = d.Command("On")(nil) - gobottest.Assert(t, err.(error), errors.New("pwm error")) + assert.ErrorContains(t, err.(error), "pwm error") err = d.Command("Off")(nil) - gobottest.Assert(t, err.(error), errors.New("pwm error")) + assert.ErrorContains(t, err.(error), "pwm error") err = d.Command("SetRGB")(map[string]interface{}{"r": 0xff, "g": 0xff, "b": 0xff}) - gobottest.Assert(t, err.(error), errors.New("pwm error")) + assert.ErrorContains(t, err.(error), "pwm error") } func TestRgbLedDriverStart(t *testing.T) { d := initTestRgbLedDriver() - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestRgbLedDriverHalt(t *testing.T) { d := initTestRgbLedDriver() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestRgbLedDriverToggle(t *testing.T) { d := initTestRgbLedDriver() _ = d.Off() _ = d.Toggle() - gobottest.Assert(t, d.State(), true) + assert.True(t, d.State()) _ = d.Toggle() - gobottest.Assert(t, d.State(), false) + assert.False(t, d.State()) } func TestRgbLedDriverSetLevel(t *testing.T) { a := newGpioTestAdaptor() d := NewRgbLedDriver(a, "1", "2", "3") - gobottest.Assert(t, d.SetLevel("1", 150), nil) + assert.NoError(t, d.SetLevel("1", 150)) d = NewRgbLedDriver(a, "1", "2", "3") - a.testAdaptorPwmWrite = func(string, byte) (err error) { + a.pwmWriteFunc = func(string, byte) (err error) { err = errors.New("pwm error") return } - gobottest.Assert(t, d.SetLevel("1", 150), errors.New("pwm error")) + assert.ErrorContains(t, d.SetLevel("1", 150), "pwm error") } func TestRgbLedDriverDefaultName(t *testing.T) { a := newGpioTestAdaptor() d := NewRgbLedDriver(a, "1", "2", "3") - gobottest.Assert(t, strings.HasPrefix(d.Name(), "RGB"), true) + assert.True(t, strings.HasPrefix(d.Name(), "RGB")) } func TestRgbLedDriverSetName(t *testing.T) { a := newGpioTestAdaptor() d := NewRgbLedDriver(a, "1", "2", "3") d.SetName("mybot") - gobottest.Assert(t, d.Name(), "mybot") + assert.Equal(t, "mybot", d.Name()) } diff --git a/drivers/gpio/servo_driver.go b/drivers/gpio/servo_driver.go index 53a560bf8..461b842f7 100644 --- a/drivers/gpio/servo_driver.go +++ b/drivers/gpio/servo_driver.go @@ -43,7 +43,6 @@ func NewServoDriver(a ServoWriter, pin string) *ServoDriver { }) return s - } // Name returns the ServoDrivers name diff --git a/drivers/gpio/servo_driver_test.go b/drivers/gpio/servo_driver_test.go index d34094d4b..5aad8c953 100644 --- a/drivers/gpio/servo_driver_test.go +++ b/drivers/gpio/servo_driver_test.go @@ -5,8 +5,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*ServoDriver)(nil) @@ -21,69 +21,69 @@ func TestServoDriver(t *testing.T) { a := newGpioTestAdaptor() d := NewServoDriver(a, "1") - gobottest.Assert(t, d.Pin(), "1") - gobottest.Refute(t, d.Connection(), nil) + assert.Equal(t, "1", d.Pin()) + assert.NotNil(t, d.Connection()) - a.testAdaptorServoWrite = func(string, byte) (err error) { + a.servoWriteFunc = func(string, byte) (err error) { return errors.New("pwm error") } err = d.Command("Min")(nil) - gobottest.Assert(t, err.(error), errors.New("pwm error")) + assert.ErrorContains(t, err.(error), "pwm error") err = d.Command("Center")(nil) - gobottest.Assert(t, err.(error), errors.New("pwm error")) + assert.ErrorContains(t, err.(error), "pwm error") err = d.Command("Max")(nil) - gobottest.Assert(t, err.(error), errors.New("pwm error")) + assert.ErrorContains(t, err.(error), "pwm error") err = d.Command("Move")(map[string]interface{}{"angle": 100.0}) - gobottest.Assert(t, err.(error), errors.New("pwm error")) + assert.ErrorContains(t, err.(error), "pwm error") } func TestServoDriverStart(t *testing.T) { d := initTestServoDriver() - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestServoDriverHalt(t *testing.T) { d := initTestServoDriver() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestServoDriverMove(t *testing.T) { d := initTestServoDriver() _ = d.Move(100) - gobottest.Assert(t, d.CurrentAngle, uint8(100)) + assert.Equal(t, uint8(100), d.CurrentAngle) err := d.Move(200) - gobottest.Assert(t, err, ErrServoOutOfRange) + assert.Equal(t, ErrServoOutOfRange, err) } func TestServoDriverMin(t *testing.T) { d := initTestServoDriver() _ = d.Min() - gobottest.Assert(t, d.CurrentAngle, uint8(0)) + assert.Equal(t, uint8(0), d.CurrentAngle) } func TestServoDriverMax(t *testing.T) { d := initTestServoDriver() _ = d.Max() - gobottest.Assert(t, d.CurrentAngle, uint8(180)) + assert.Equal(t, uint8(180), d.CurrentAngle) } func TestServoDriverCenter(t *testing.T) { d := initTestServoDriver() _ = d.Center() - gobottest.Assert(t, d.CurrentAngle, uint8(90)) + assert.Equal(t, uint8(90), d.CurrentAngle) } func TestServoDriverDefaultName(t *testing.T) { d := initTestServoDriver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "Servo"), true) + assert.True(t, strings.HasPrefix(d.Name(), "Servo")) } func TestServoDriverSetName(t *testing.T) { d := initTestServoDriver() d.SetName("mybot") - gobottest.Assert(t, d.Name(), "mybot") + assert.Equal(t, "mybot", d.Name()) } diff --git a/drivers/gpio/stepper_driver.go b/drivers/gpio/stepper_driver.go index 25a3d2c20..1a9469a33 100644 --- a/drivers/gpio/stepper_driver.go +++ b/drivers/gpio/stepper_driver.go @@ -19,21 +19,21 @@ var StepperModes = struct { DualPhaseStepping [][4]byte HalfStepping [][4]byte }{ - //1 cycle = 4 steps with lesser torque + // 1 cycle = 4 steps with lesser torque SinglePhaseStepping: [][4]byte{ {1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}, }, - //1 cycle = 4 steps with higher torque and current + // 1 cycle = 4 steps with higher torque and current DualPhaseStepping: [][4]byte{ {1, 0, 0, 1}, {1, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 1, 1}, }, - //1 cycle = 8 steps with lesser torque than full stepping + // 1 cycle = 8 steps with lesser torque than full stepping HalfStepping: [][4]byte{ {1, 0, 0, 1}, {1, 0, 0, 0}, @@ -110,7 +110,7 @@ func (s *StepperDriver) Start() error { return nil } // Run continuously runs the stepper func (s *StepperDriver) Run() error { - //halt if already moving + // halt if already moving if s.moving { if err := s.Halt(); err != nil { return err @@ -196,7 +196,7 @@ func (s *StepperDriver) Move(stepsToMove int) error { } if s.moving { - //stop previous motion + // stop previous motion if err := s.Halt(); err != nil { return err } @@ -228,7 +228,7 @@ func (s *StepperDriver) Move(stepsToMove int) error { // getDelayPerStep gives the delay per step func (s *StepperDriver) getDelayPerStep() time.Duration { - //Do not remove *1000 and change duration to time.Millisecond. It has been done for a reason + // Do not remove *1000 and change duration to time.Millisecond. It has been done for a reason return time.Duration(60000*1000/(s.stepsPerRev*s.speed)) * time.Microsecond } @@ -239,7 +239,7 @@ func (s *StepperDriver) GetCurrentStep() int { // GetMaxSpeed gives the max RPM of motor func (s *StepperDriver) GetMaxSpeed() uint { - //considering time for 1 rev as no of steps per rev * 1.5 (min time req between each step) + // considering time for 1 rev as no of steps per rev * 1.5 (min time req between each step) return uint(60000 / (float64(s.stepsPerRev) * 1.5)) } diff --git a/drivers/gpio/stepper_driver_test.go b/drivers/gpio/stepper_driver_test.go index d41449c30..4c3271b6b 100644 --- a/drivers/gpio/stepper_driver_test.go +++ b/drivers/gpio/stepper_driver_test.go @@ -1,12 +1,11 @@ package gpio import ( - "errors" "strings" "testing" "time" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) const ( @@ -20,7 +19,7 @@ func initStepperMotorDriver() *StepperDriver { func TestStepperDriverRun(t *testing.T) { d := initStepperMotorDriver() _ = d.Run() - gobottest.Assert(t, d.IsMoving(), true) + assert.True(t, d.IsMoving()) } func TestStepperDriverHalt(t *testing.T) { @@ -28,61 +27,61 @@ func TestStepperDriverHalt(t *testing.T) { _ = d.Run() time.Sleep(200 * time.Millisecond) _ = d.Halt() - gobottest.Assert(t, d.IsMoving(), false) + assert.False(t, d.IsMoving()) } func TestStepperDriverDefaultName(t *testing.T) { d := initStepperMotorDriver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "Stepper"), true) + assert.True(t, strings.HasPrefix(d.Name(), "Stepper")) } func TestStepperDriverSetName(t *testing.T) { name := "SomeStepperSriver" d := initStepperMotorDriver() d.SetName(name) - gobottest.Assert(t, d.Name(), name) + assert.Equal(t, name, d.Name()) } func TestStepperDriverSetDirection(t *testing.T) { dir := "backward" d := initStepperMotorDriver() _ = d.SetDirection(dir) - gobottest.Assert(t, d.direction, dir) + assert.Equal(t, dir, d.direction) } func TestStepperDriverDefaultDirection(t *testing.T) { d := initStepperMotorDriver() - gobottest.Assert(t, d.direction, "forward") + assert.Equal(t, "forward", d.direction) } func TestStepperDriverInvalidDirection(t *testing.T) { d := initStepperMotorDriver() err := d.SetDirection("reverse") - gobottest.Assert(t, err, errors.New("Invalid direction. Value should be forward or backward")) + assert.ErrorContains(t, err, "Invalid direction. Value should be forward or backward") } func TestStepperDriverMoveForward(t *testing.T) { d := initStepperMotorDriver() _ = d.Move(1) - gobottest.Assert(t, d.GetCurrentStep(), 1) + assert.Equal(t, 1, d.GetCurrentStep()) _ = d.Move(10) - gobottest.Assert(t, d.GetCurrentStep(), 11) + assert.Equal(t, 11, d.GetCurrentStep()) } func TestStepperDriverMoveBackward(t *testing.T) { d := initStepperMotorDriver() _ = d.Move(-1) - gobottest.Assert(t, d.GetCurrentStep(), stepsInRev-1) + assert.Equal(t, stepsInRev-1, d.GetCurrentStep()) _ = d.Move(-10) - gobottest.Assert(t, d.GetCurrentStep(), stepsInRev-11) + assert.Equal(t, stepsInRev-11, d.GetCurrentStep()) } func TestStepperDriverMoveFullRotation(t *testing.T) { d := initStepperMotorDriver() _ = d.Move(stepsInRev) - gobottest.Assert(t, d.GetCurrentStep(), 0) + assert.Equal(t, 0, d.GetCurrentStep()) } func TestStepperDriverMotorSetSpeedMoreThanMax(t *testing.T) { @@ -90,7 +89,7 @@ func TestStepperDriverMotorSetSpeedMoreThanMax(t *testing.T) { m := d.GetMaxSpeed() _ = d.SetSpeed(m + 1) - gobottest.Assert(t, m, d.speed) + assert.Equal(t, d.speed, m) } func TestStepperDriverMotorSetSpeedLessOrEqualMax(t *testing.T) { @@ -98,8 +97,8 @@ func TestStepperDriverMotorSetSpeedLessOrEqualMax(t *testing.T) { m := d.GetMaxSpeed() _ = d.SetSpeed(m - 1) - gobottest.Assert(t, m-1, d.speed) + assert.Equal(t, d.speed, m-1) _ = d.SetSpeed(m) - gobottest.Assert(t, m, d.speed) + assert.Equal(t, d.speed, m) } diff --git a/drivers/gpio/tm1638_driver.go b/drivers/gpio/tm1638_driver.go index 4b23bb360..588671433 100644 --- a/drivers/gpio/tm1638_driver.go +++ b/drivers/gpio/tm1638_driver.go @@ -2,7 +2,6 @@ package gpio import ( "math" - "strings" "gobot.io/x/gobot/v2" @@ -62,7 +61,6 @@ func NewTM1638Driver(a gobot.Connection, clockPin string, dataPin string, strobe // Start initializes the tm1638, it uses a SPI-like communication protocol func (t *TM1638Driver) Start() error { - if err := t.pinStrobe.On(); err != nil { return err } diff --git a/drivers/gpio/tm1638_driver_test.go b/drivers/gpio/tm1638_driver_test.go index ccff9152e..dc5ce2718 100644 --- a/drivers/gpio/tm1638_driver_test.go +++ b/drivers/gpio/tm1638_driver_test.go @@ -4,8 +4,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*TM1638Driver)(nil) @@ -32,41 +32,41 @@ func TestTM1638Driver(t *testing.T) { func TestTM1638DriverStart(t *testing.T) { d := initTestTM1638Driver() - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestTM1638DriverHalt(t *testing.T) { d := initTestTM1638Driver() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestTM1638DriverDefaultName(t *testing.T) { d := initTestTM1638Driver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "TM1638"), true) + assert.True(t, strings.HasPrefix(d.Name(), "TM1638")) } func TestTM1638DriverSetName(t *testing.T) { d := initTestTM1638Driver() d.SetName("mybot") - gobottest.Assert(t, d.Name(), "mybot") + assert.Equal(t, "mybot", d.Name()) } func TestTM1638DriverFromStringToByteArray(t *testing.T) { d := initTestTM1638Driver() data := d.fromStringToByteArray("Hello World") - gobottest.Assert(t, []byte{0x76, 0x7B, 0x30, 0x30, 0x5C, 0x00, 0x1D, 0x5C, 0x50, 0x30, 0x5E}, data) + assert.Equal(t, data, []byte{0x76, 0x7B, 0x30, 0x30, 0x5C, 0x00, 0x1D, 0x5C, 0x50, 0x30, 0x5E}) } func TestTM1638DriverAddFonts(t *testing.T) { d := initTestTM1638Driver() d.AddFonts(map[string]byte{"µ": 0x1C, "ß": 0x7F}) data := d.fromStringToByteArray("µß") - gobottest.Assert(t, []byte{0x1C, 0x7F}, data) + assert.Equal(t, data, []byte{0x1C, 0x7F}) } func TestTM1638DriverClearFonts(t *testing.T) { d := initTestTM1638Driver() d.ClearFonts() data := d.fromStringToByteArray("Hello World") - gobottest.Assert(t, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, data) + assert.Equal(t, data, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) } diff --git a/drivers/i2c/README.md b/drivers/i2c/README.md index b17c583a5..ea6e4ba32 100644 --- a/drivers/i2c/README.md +++ b/drivers/i2c/README.md @@ -12,8 +12,9 @@ Please refer to the main [README.md](https://github.com/hybridgroup/gobot/blob/r Gobot has a extensible system for connecting to hardware devices. The following i2c devices are currently supported: -- Adafruit 2x16 RGB-LCD with 5 keys -- Adafruit Motor Hat +- Adafruit 1109 2x16 RGB-LCD with 5 keys +- Adafruit 2327 16-Channel PWM/Servo HAT Hat +- Adafruit 2348 DC and Stepper Motor Hat - ADS1015 Analog to Digital Converter - ADS1115 Analog to Digital Converter - ADXL345 Digital Accelerometer diff --git a/drivers/i2c/adafruit1109_driver.go b/drivers/i2c/adafruit1109_driver.go index 7bd4afa7c..feae2530f 100644 --- a/drivers/i2c/adafruit1109_driver.go +++ b/drivers/i2c/adafruit1109_driver.go @@ -79,7 +79,7 @@ func NewAdafruit1109Driver(a Connector, options ...func(Config)) *Adafruit1109Dr D7: d.dataPinD7.String(), } - //rwPin := "B_6" not mapped in HD44780 driver + // rwPin := "B_6" not mapped in HD44780 driver // at test initialization, there seems rows and columns be switched // but inside the driver the row is used as row and col as column rows := 2 diff --git a/drivers/i2c/adafruit1109_driver_test.go b/drivers/i2c/adafruit1109_driver_test.go index 8fcb5a94d..bea0e179f 100644 --- a/drivers/i2c/adafruit1109_driver_test.go +++ b/drivers/i2c/adafruit1109_driver_test.go @@ -6,8 +6,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*Adafruit1109Driver)(nil) @@ -23,49 +23,49 @@ func TestNewAdafruit1109Driver(t *testing.T) { if !ok { t.Errorf("NewAdafruit1109Driver() should have returned a *Adafruit1109Driver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Refute(t, d.Connection(), nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "Adafruit1109"), true) - gobottest.Assert(t, strings.Contains(d.Name(), "MCP23017"), true) - gobottest.Assert(t, strings.Contains(d.Name(), "HD44780"), true) - gobottest.Refute(t, d.MCP23017Driver, nil) - gobottest.Refute(t, d.HD44780Driver, nil) - gobottest.Refute(t, d.redPin, nil) - gobottest.Refute(t, d.greenPin, nil) - gobottest.Refute(t, d.bluePin, nil) - gobottest.Refute(t, d.selectPin, nil) - gobottest.Refute(t, d.upPin, nil) - gobottest.Refute(t, d.downPin, nil) - gobottest.Refute(t, d.leftPin, nil) - gobottest.Refute(t, d.rightPin, nil) - gobottest.Refute(t, d.rwPin, nil) - gobottest.Refute(t, d.rsPin, nil) - gobottest.Refute(t, d.enPin, nil) - gobottest.Refute(t, d.dataPinD4, nil) - gobottest.Refute(t, d.dataPinD5, nil) - gobottest.Refute(t, d.dataPinD6, nil) - gobottest.Refute(t, d.dataPinD7, nil) + assert.NotNil(t, d.Driver) + assert.NotNil(t, d.Connection()) + assert.True(t, strings.HasPrefix(d.Name(), "Adafruit1109")) + assert.Contains(t, d.Name(), "MCP23017") + assert.Contains(t, d.Name(), "HD44780") + assert.NotNil(t, d.MCP23017Driver) + assert.NotNil(t, d.HD44780Driver) + assert.NotNil(t, d.redPin) + assert.NotNil(t, d.greenPin) + assert.NotNil(t, d.bluePin) + assert.NotNil(t, d.selectPin) + assert.NotNil(t, d.upPin) + assert.NotNil(t, d.downPin) + assert.NotNil(t, d.leftPin) + assert.NotNil(t, d.rightPin) + assert.NotNil(t, d.rwPin) + assert.NotNil(t, d.rsPin) + assert.NotNil(t, d.enPin) + assert.NotNil(t, d.dataPinD4) + assert.NotNil(t, d.dataPinD5) + assert.NotNil(t, d.dataPinD6) + assert.NotNil(t, d.dataPinD7) } func TestAdafruit1109Connect(t *testing.T) { d, _ := initTestAdafruit1109WithStubbedAdaptor() - gobottest.Assert(t, d.Connect(), nil) + assert.NoError(t, d.Connect()) } func TestAdafruit1109Finalize(t *testing.T) { d, _ := initTestAdafruit1109WithStubbedAdaptor() - gobottest.Assert(t, d.Finalize(), nil) + assert.NoError(t, d.Finalize()) } func TestAdafruit1109SetName(t *testing.T) { d, _ := initTestAdafruit1109WithStubbedAdaptor() d.SetName("foo") - gobottest.Assert(t, d.name, "foo") + assert.Equal(t, "foo", d.name) } func TestAdafruit1109Start(t *testing.T) { d, _ := initTestAdafruit1109WithStubbedAdaptor() - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestAdafruit1109StartWriteErr(t *testing.T) { @@ -73,7 +73,7 @@ func TestAdafruit1109StartWriteErr(t *testing.T) { adaptor.i2cWriteImpl = func([]byte) (int, error) { return 0, errors.New("write error") } - gobottest.Assert(t, d.Start(), errors.New("write error")) + assert.ErrorContains(t, d.Start(), "write error") } func TestAdafruit1109StartReadErr(t *testing.T) { @@ -81,17 +81,17 @@ func TestAdafruit1109StartReadErr(t *testing.T) { adaptor.i2cReadImpl = func([]byte) (int, error) { return 0, errors.New("read error") } - gobottest.Assert(t, d.Start(), errors.New("MCP write-read: MCP write-ReadByteData(reg=0): read error")) + assert.ErrorContains(t, d.Start(), "MCP write-read: MCP write-ReadByteData(reg=0): read error") } func TestAdafruit1109Halt(t *testing.T) { d, _ := initTestAdafruit1109WithStubbedAdaptor() _ = d.Start() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestAdafruit1109DigitalRead(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { read uint8 wantReg uint8 }{ @@ -128,17 +128,17 @@ func TestAdafruit1109DigitalRead(t *testing.T) { // act got, err := d.DigitalRead(name) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, numCallsRead, 1) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], tc.wantReg) - gobottest.Assert(t, got, 1) + assert.NoError(t, err) + assert.Equal(t, 1, numCallsRead) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, tc.wantReg, a.written[0]) + assert.Equal(t, 1, got) }) } } func TestAdafruit1109SelectButton(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { read uint8 want uint8 }{ @@ -160,15 +160,15 @@ func TestAdafruit1109SelectButton(t *testing.T) { // act got, err := d.SelectButton() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, numCallsRead, 1) - gobottest.Assert(t, got, tc.want) + assert.NoError(t, err) + assert.Equal(t, 1, numCallsRead) + assert.Equal(t, tc.want, got) }) } } func TestAdafruit1109UpButton(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { read uint8 want uint8 }{ @@ -190,15 +190,15 @@ func TestAdafruit1109UpButton(t *testing.T) { // act got, err := d.UpButton() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, numCallsRead, 1) - gobottest.Assert(t, got, tc.want) + assert.NoError(t, err) + assert.Equal(t, 1, numCallsRead) + assert.Equal(t, tc.want, got) }) } } func TestAdafruit1109DownButton(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { read uint8 want uint8 }{ @@ -220,15 +220,15 @@ func TestAdafruit1109DownButton(t *testing.T) { // act got, err := d.DownButton() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, numCallsRead, 1) - gobottest.Assert(t, got, tc.want) + assert.NoError(t, err) + assert.Equal(t, 1, numCallsRead) + assert.Equal(t, tc.want, got) }) } } func TestAdafruit1109LeftButton(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { read uint8 want uint8 }{ @@ -250,15 +250,15 @@ func TestAdafruit1109LeftButton(t *testing.T) { // act got, err := d.LeftButton() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, numCallsRead, 1) - gobottest.Assert(t, got, tc.want) + assert.NoError(t, err) + assert.Equal(t, 1, numCallsRead) + assert.Equal(t, tc.want, got) }) } } func TestAdafruit1109RightButton(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { read uint8 want uint8 }{ @@ -280,9 +280,9 @@ func TestAdafruit1109RightButton(t *testing.T) { // act got, err := d.RightButton() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, numCallsRead, 1) - gobottest.Assert(t, got, tc.want) + assert.NoError(t, err) + assert.Equal(t, 1, numCallsRead) + assert.Equal(t, tc.want, got) }) } } @@ -297,7 +297,7 @@ func TestAdafruit1109_parseID(t *testing.T) { // act got := adafruit1109ParseID(id) // assert - gobottest.Assert(t, got, adafruit1109PortPin{port, pin}) + assert.Equal(t, adafruit1109PortPin{port, pin}, got) }) } } diff --git a/drivers/i2c/adafruit2327_driver.go b/drivers/i2c/adafruit2327_driver.go new file mode 100644 index 000000000..c26ff5d87 --- /dev/null +++ b/drivers/i2c/adafruit2327_driver.go @@ -0,0 +1,45 @@ +package i2c + +import ( + "gobot.io/x/gobot/v2" +) + +// Adafruit2327Driver is a driver for Adafruit 16-Channel PWM/Servo HAT & Bonnet - a Raspberry Pi add-on, based on +// PCA9685. This driver just wraps the PCA9685Driver. +// Stacking 62 of them is possible (addresses 0x40..0x7E), for controlling up to 992 servos. +// datasheet: +// https://cdn-learn.adafruit.com/downloads/pdf/adafruit-16-channel-pwm-servo-hat-for-raspberry-pi.pdf +type Adafruit2327Driver struct { + *PCA9685Driver +} + +// NewAdafruit2327Driver initializes a new driver for PWM servos. +// Params: +// +// c Connector - the Adaptor to use with this Driver +// +// Optional params: +// +// i2c.WithBus(int): bus to use with this driver +// i2c.WithAddress(int): address to use with this driver +func NewAdafruit2327Driver(c Connector, options ...func(Config)) *Adafruit2327Driver { + pca := NewPCA9685Driver(c, options...) // the default address of the driver is already 0x40 + pca.SetName(gobot.DefaultName("Adafruit2327ServoHat")) + d := &Adafruit2327Driver{ + PCA9685Driver: pca, + } + + // TODO: add API funcs + return d +} + +// SetServoMotorFreq sets the frequency for the currently addressed PWM Servo HAT. +func (a *Adafruit2327Driver) SetServoMotorFreq(freq float64) error { + return a.SetPWMFreq(float32(freq)) +} + +// SetServoMotorPulse is a convenience function to specify the 'tick' value, +// between 0-4095, when the signal will turn on, and when it will turn off. +func (a *Adafruit2327Driver) SetServoMotorPulse(channel byte, on, off int32) error { + return a.SetPWM(int(channel), uint16(on), uint16(off)) +} diff --git a/drivers/i2c/adafruit2327_driver_test.go b/drivers/i2c/adafruit2327_driver_test.go new file mode 100644 index 000000000..9690be1fa --- /dev/null +++ b/drivers/i2c/adafruit2327_driver_test.go @@ -0,0 +1,94 @@ +package i2c + +import ( + "errors" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "gobot.io/x/gobot/v2" +) + +// this ensures that the implementation implements the gobot.Driver interface +var _ gobot.Driver = (*Adafruit2327Driver)(nil) + +func initTestAdafruit2327WithStubbedAdaptor() (*Adafruit2327Driver, *i2cTestAdaptor) { + a := newI2cTestAdaptor() + d := NewAdafruit2327Driver(a) + if err := d.Start(); err != nil { + panic(err) + } + return d, a +} + +func TestNewAdafruit2327Driver(t *testing.T) { + // arrange & act + d := NewAdafruit2327Driver(newI2cTestAdaptor()) + // assert + assert.IsType(t, &Adafruit2327Driver{}, d) + assert.True(t, strings.HasPrefix(d.Name(), "Adafruit2327ServoHat")) + assert.Equal(t, 0x40, d.defaultAddress) +} + +func TestAdafruit2327Options(t *testing.T) { + // This is a general test, that options are applied in constructor by using the common WithBus() option and + // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". + // arrange & act + d := NewAdafruit2327Driver(newI2cTestAdaptor(), WithBus(2)) + // assert + assert.Equal(t, 2, d.GetBusOrDefault(1)) +} + +func TestAdafruit2327SetServoMotorFreq(t *testing.T) { + // arrange + d, a := initTestAdafruit2327WithStubbedAdaptor() + a.written = []byte{} // reset writes of former test + const freq = 60.0 + // act + err := d.SetServoMotorFreq(freq) + // assert + assert.NoError(t, err) + assert.Equal(t, 9, len(a.written)) // detailed test, see "TestPCA9685SetPWMFreq" +} + +func TestAdafruit2327SetServoMotorFreqError(t *testing.T) { + // arrange + d, a := initTestAdafruit2327WithStubbedAdaptor() + a.i2cWriteImpl = func([]byte) (int, error) { + return 0, errors.New("write error") + } + const freq = 60.0 + // act & assert + assert.ErrorContains(t, d.SetServoMotorFreq(freq), "write error") +} + +func TestAdafruit2327SetServoMotorPulse(t *testing.T) { + // arrange + d, a := initTestAdafruit2327WithStubbedAdaptor() + a.written = []byte{} // reset writes of former test + const ( + channel byte = 7 + on int32 = 1234 + off int32 = 4321 + ) + // act + err := d.SetServoMotorPulse(channel, on, off) + // assert + assert.NoError(t, err) + assert.Equal(t, 8, len(a.written)) // detailed test, see "TestPCA9685SetPWM" +} + +func TestAdafruit2327SetServoMotorPulseError(t *testing.T) { + // arrange + d, a := initTestAdafruit2327WithStubbedAdaptor() + a.i2cWriteImpl = func([]byte) (int, error) { + return 0, errors.New("write error") + } + const ( + channel byte = 7 + on int32 = 1234 + off int32 = 4321 + ) + // act & assert + assert.ErrorContains(t, d.SetServoMotorPulse(channel, on, off), "write error") +} diff --git a/drivers/i2c/adafruit2348_driver.go b/drivers/i2c/adafruit2348_driver.go new file mode 100644 index 000000000..f6014b2b6 --- /dev/null +++ b/drivers/i2c/adafruit2348_driver.go @@ -0,0 +1,334 @@ +package i2c + +import ( + "errors" + "log" + "sync" + "time" + + "gobot.io/x/gobot/v2" +) + +const adafruit2348Debug = false // Set this to true to see debug output + +const ( + adafruit2348MotorHatDefaultAddress = 0x60 + adafruit2348StepperMicrosteps = 8 +) + +// Adafruit2348Direction declares a type for specification of the motor direction +type Adafruit2348Direction int + +// Adafruit2348StepStyle declares a type for specification of the stepper motor rotation +type Adafruit2348StepStyle int + +// constants for running the motor in different direction or release +const ( + Adafruit2348Forward Adafruit2348Direction = iota // 0 + Adafruit2348Backward // 1 + Adafruit2348Release // 2 +) + +// constants for running the stepper motor in different modes +const ( + Adafruit2348Single Adafruit2348StepStyle = iota // 0 + Adafruit2348Double // 1 + Adafruit2348Interleave // 2 + Adafruit2348Microstep // 3 +) + +type adafruit2348DCMotor struct { + pwmPin, in1Pin, in2Pin byte +} + +type adafruit2348StepperMotor struct { + pwmPinA, pwmPinB byte + ain1, ain2 byte + bin1, bin2 byte + secPerStep float64 + currentStep, revSteps int +} + +// Adafruit2348Driver is a driver for Adafruit DC and Stepper Motor HAT - a Raspberry Pi add-on, based on PCA9685. +// The HAT can drive up to 4 DC or 2 stepper motors with full PWM speed and direction control over I2C. +// This driver wraps the PCA9685Driver. +// Stacking 32 of them is possible (addresses 0x60..0x80), for controlling up to 64 stepper motors or 128 DC motors. +// datasheet: +// https://cdn-learn.adafruit.com/downloads/pdf/adafruit2348-dc-and-stepper-motor-hat-for-raspberry-pi.pdf +type Adafruit2348Driver struct { + *PCA9685Driver + dcMotors []adafruit2348DCMotor + stepperMotors []adafruit2348StepperMotor + stepperMicrostepCurve []int + step2coils map[int][]int32 + stepperSpeedMutex *sync.Mutex +} + +// NewAdafruit2348Driver initializes a new driver for DC and stepper motors. +// Params: +// +// c Connector - the Adaptor to use with this Driver +// +// Optional params: +// +// i2c.WithBus(int): bus to use with this driver +// i2c.WithAddress(int): address to use with this driver +func NewAdafruit2348Driver(c Connector, options ...func(Config)) *Adafruit2348Driver { + var dc []adafruit2348DCMotor + var st []adafruit2348StepperMotor + for i := 0; i < 4; i++ { + switch { + case i == 0: + dc = append(dc, adafruit2348DCMotor{pwmPin: 8, in1Pin: 10, in2Pin: 9}) + st = append(st, adafruit2348StepperMotor{ + pwmPinA: 8, pwmPinB: 13, + ain1: 10, ain2: 9, bin1: 11, bin2: 12, revSteps: 200, secPerStep: 0.1, + }) + case i == 1: + dc = append(dc, adafruit2348DCMotor{pwmPin: 13, in1Pin: 11, in2Pin: 12}) + st = append(st, adafruit2348StepperMotor{ + pwmPinA: 2, pwmPinB: 7, + ain1: 4, ain2: 3, bin1: 5, bin2: 6, revSteps: 200, secPerStep: 0.1, + }) + case i == 2: + dc = append(dc, adafruit2348DCMotor{pwmPin: 2, in1Pin: 4, in2Pin: 3}) + case i == 3: + dc = append(dc, adafruit2348DCMotor{pwmPin: 7, in1Pin: 5, in2Pin: 6}) + } + } + + // external given address must be able to override the default one + o := append([]func(Config){WithAddress(adafruit2348MotorHatDefaultAddress)}, options...) + pca := NewPCA9685Driver(c, o...) + pca.SetName(gobot.DefaultName("Adafruit2348MotorHat")) + d := &Adafruit2348Driver{ + PCA9685Driver: pca, + dcMotors: dc, + stepperMotors: st, + stepperMicrostepCurve: []int{0, 50, 98, 142, 180, 212, 236, 250, 255}, + step2coils: map[int][]int32{ + 0: {1, 0, 0, 0}, + 1: {1, 1, 0, 0}, + 2: {0, 1, 0, 0}, + 3: {0, 1, 1, 0}, + 4: {0, 0, 1, 0}, + 5: {0, 0, 1, 1}, + 6: {0, 0, 0, 1}, + 7: {1, 0, 0, 1}, + }, + stepperSpeedMutex: &sync.Mutex{}, + } + + // TODO: add API funcs + return d +} + +// SetDCMotorSpeed will set the appropriate pins to run the specified DC motor for the given speed. +func (a *Adafruit2348Driver) SetDCMotorSpeed(dcMotor int, speed int32) error { + return a.SetPWM(int(a.dcMotors[dcMotor].pwmPin), 0, uint16(speed*16)) +} + +// RunDCMotor will set the appropriate pins to run the specified DC motor for the given direction. +func (a *Adafruit2348Driver) RunDCMotor(dcMotor int, dir Adafruit2348Direction) error { + switch { + case dir == Adafruit2348Forward: + if err := a.setPin(a.dcMotors[dcMotor].in2Pin, 0); err != nil { + return err + } + if err := a.setPin(a.dcMotors[dcMotor].in1Pin, 1); err != nil { + return err + } + case dir == Adafruit2348Backward: + if err := a.setPin(a.dcMotors[dcMotor].in1Pin, 0); err != nil { + return err + } + if err := a.setPin(a.dcMotors[dcMotor].in2Pin, 1); err != nil { + return err + } + case dir == Adafruit2348Release: + if err := a.setPin(a.dcMotors[dcMotor].in1Pin, 0); err != nil { + return err + } + if err := a.setPin(a.dcMotors[dcMotor].in2Pin, 0); err != nil { + return err + } + } + return nil +} + +// SetStepperMotorSpeed sets the seconds-per-step for the given stepper motor. It is applied in the next cycle. +func (a *Adafruit2348Driver) SetStepperMotorSpeed(stepperMotor int, rpm int) error { + a.stepperSpeedMutex.Lock() + defer a.stepperSpeedMutex.Unlock() + + revSteps := a.stepperMotors[stepperMotor].revSteps + a.stepperMotors[stepperMotor].secPerStep = 60.0 / float64(revSteps*rpm) + return nil +} + +// Step will rotate the stepper motor the given number of steps, in the given direction and step style. +func (a *Adafruit2348Driver) Step(motor, steps int, dir Adafruit2348Direction, style Adafruit2348StepStyle) error { + a.stepperSpeedMutex.Lock() + defer a.stepperSpeedMutex.Unlock() + + secPerStep := a.stepperMotors[motor].secPerStep + var latestStep int + var err error + if style == Adafruit2348Interleave { + secPerStep = secPerStep / 2.0 + } + if style == Adafruit2348Microstep { + secPerStep /= float64(adafruit2348StepperMicrosteps) + steps *= adafruit2348StepperMicrosteps + } + if adafruit2348Debug { + log.Printf("[adafruit2348_driver] %f seconds per step", secPerStep) + } + for i := 0; i < steps; i++ { + if latestStep, err = a.oneStep(motor, dir, style); err != nil { + return err + } + time.Sleep(time.Duration(secPerStep) * time.Second) + } + // As documented in the Adafruit python driver: + // This is an edge case, if we are in between full steps, keep going to end on a full step + if style == Adafruit2348Microstep { + for latestStep != 0 && latestStep != adafruit2348StepperMicrosteps { + if latestStep, err = a.oneStep(motor, dir, style); err != nil { + return err + } + time.Sleep(time.Duration(secPerStep) * time.Second) + } + } + return nil +} + +func (a *Adafruit2348Driver) oneStep(motor int, dir Adafruit2348Direction, style Adafruit2348StepStyle) (int, error) { + pwmA := 255 + pwmB := 255 + + // Determine the stepping procedure + switch { + case style == Adafruit2348Single: + if (a.stepperMotors[motor].currentStep / (adafruit2348StepperMicrosteps / 2) % 2) != 0 { + // we're at an odd step + if dir == Adafruit2348Forward { + a.stepperMotors[motor].currentStep += adafruit2348StepperMicrosteps / 2 + } else { + a.stepperMotors[motor].currentStep -= adafruit2348StepperMicrosteps / 2 + } + } else { + // go to next even step + if dir == Adafruit2348Forward { + a.stepperMotors[motor].currentStep += adafruit2348StepperMicrosteps + } else { + a.stepperMotors[motor].currentStep -= adafruit2348StepperMicrosteps + } + } + case style == Adafruit2348Double: + if (a.stepperMotors[motor].currentStep / (adafruit2348StepperMicrosteps / 2) % 2) == 0 { + // we're at an even step, weird + if dir == Adafruit2348Forward { + a.stepperMotors[motor].currentStep += adafruit2348StepperMicrosteps / 2 + } else { + a.stepperMotors[motor].currentStep -= adafruit2348StepperMicrosteps / 2 + } + } else { + // go to next odd step + if dir == Adafruit2348Forward { + a.stepperMotors[motor].currentStep += adafruit2348StepperMicrosteps + } else { + a.stepperMotors[motor].currentStep -= adafruit2348StepperMicrosteps + } + } + case style == Adafruit2348Interleave: + if dir == Adafruit2348Forward { + a.stepperMotors[motor].currentStep += adafruit2348StepperMicrosteps / 2 + } else { + a.stepperMotors[motor].currentStep -= adafruit2348StepperMicrosteps / 2 + } + case style == Adafruit2348Microstep: + if dir == Adafruit2348Forward { + a.stepperMotors[motor].currentStep++ + } else { + a.stepperMotors[motor].currentStep-- + } + // go to next step and wrap around + a.stepperMotors[motor].currentStep += adafruit2348StepperMicrosteps * 4 + a.stepperMotors[motor].currentStep %= adafruit2348StepperMicrosteps * 4 + + pwmA = 0 + pwmB = 0 + currStep := a.stepperMotors[motor].currentStep + if currStep >= 0 && currStep < adafruit2348StepperMicrosteps { + pwmA = a.stepperMicrostepCurve[adafruit2348StepperMicrosteps-currStep] + pwmB = a.stepperMicrostepCurve[currStep] + } else if currStep >= adafruit2348StepperMicrosteps && currStep < adafruit2348StepperMicrosteps*2 { + pwmA = a.stepperMicrostepCurve[currStep-adafruit2348StepperMicrosteps] + pwmB = a.stepperMicrostepCurve[adafruit2348StepperMicrosteps*2-currStep] + } else if currStep >= adafruit2348StepperMicrosteps*2 && currStep < adafruit2348StepperMicrosteps*3 { + pwmA = a.stepperMicrostepCurve[adafruit2348StepperMicrosteps*3-currStep] + pwmB = a.stepperMicrostepCurve[currStep-adafruit2348StepperMicrosteps*2] + } else if currStep >= adafruit2348StepperMicrosteps*3 && currStep < adafruit2348StepperMicrosteps*4 { + pwmA = a.stepperMicrostepCurve[currStep-adafruit2348StepperMicrosteps*3] + pwmB = a.stepperMicrostepCurve[adafruit2348StepperMicrosteps*4-currStep] + } + } // switch + + // go to next 'step' and wrap around + a.stepperMotors[motor].currentStep += adafruit2348StepperMicrosteps * 4 + a.stepperMotors[motor].currentStep %= adafruit2348StepperMicrosteps * 4 + + // only really used for microstepping, otherwise always on! + if err := a.SetPWM(int(a.stepperMotors[motor].pwmPinA), 0, uint16(pwmA*16)); err != nil { + return 0, err + } + if err := a.SetPWM(int(a.stepperMotors[motor].pwmPinB), 0, uint16(pwmB*16)); err != nil { + return 0, err + } + var coils []int32 + currStep := a.stepperMotors[motor].currentStep + if style == Adafruit2348Microstep { + switch { + case currStep >= 0 && currStep < adafruit2348StepperMicrosteps: + coils = []int32{1, 1, 0, 0} + case currStep >= adafruit2348StepperMicrosteps && currStep < adafruit2348StepperMicrosteps*2: + coils = []int32{0, 1, 1, 0} + case currStep >= adafruit2348StepperMicrosteps*2 && currStep < adafruit2348StepperMicrosteps*3: + coils = []int32{0, 0, 1, 1} + case currStep >= adafruit2348StepperMicrosteps*3 && currStep < adafruit2348StepperMicrosteps*4: + coils = []int32{1, 0, 0, 1} + } + } else { + // step-2-coils is initialized in init() + coils = a.step2coils[(currStep / (adafruit2348StepperMicrosteps / 2))] + } + if adafruit2348Debug { + log.Printf("[adafruit2348_driver] currStep: %d, index into step2coils: %d\n", + currStep, (currStep / (adafruit2348StepperMicrosteps / 2))) + log.Printf("[adafruit2348_driver] coils state = %v", coils) + } + if err := a.setPin(a.stepperMotors[motor].ain2, coils[0]); err != nil { + return 0, err + } + if err := a.setPin(a.stepperMotors[motor].bin1, coils[1]); err != nil { + return 0, err + } + if err := a.setPin(a.stepperMotors[motor].ain1, coils[2]); err != nil { + return 0, err + } + if err := a.setPin(a.stepperMotors[motor].bin2, coils[3]); err != nil { + return 0, err + } + return a.stepperMotors[motor].currentStep, nil +} + +func (a *Adafruit2348Driver) setPin(pin byte, value int32) error { + if value == 0 { + return a.SetPWM(int(pin), 0, 4096) + } + if value == 1 { + return a.SetPWM(int(pin), 4096, 0) + } + return errors.New("Invalid pin") +} diff --git a/drivers/i2c/adafruit2348_driver_test.go b/drivers/i2c/adafruit2348_driver_test.go new file mode 100644 index 000000000..d668034cf --- /dev/null +++ b/drivers/i2c/adafruit2348_driver_test.go @@ -0,0 +1,162 @@ +package i2c + +import ( + "errors" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "gobot.io/x/gobot/v2" +) + +// this ensures that the implementation implements the gobot.Driver interface +var _ gobot.Driver = (*Adafruit2348Driver)(nil) + +func initTestAdafruit2348WithStubbedAdaptor() (*Adafruit2348Driver, *i2cTestAdaptor) { + a := newI2cTestAdaptor() + d := NewAdafruit2348Driver(a) + if err := d.Start(); err != nil { + panic(err) + } + return d, a +} + +func TestNewAdafruit2348Driver(t *testing.T) { + // arrange & act + d := NewAdafruit2348Driver(newI2cTestAdaptor()) + // assert + assert.IsType(t, &Adafruit2348Driver{}, d) + assert.True(t, strings.HasPrefix(d.Name(), "Adafruit2348MotorHat")) + assert.Equal(t, 0x40, d.defaultAddress) // the default address of PCA9685 driver + assert.Equal(t, 0x60, d.Config.GetAddressOrDefault(d.defaultAddress)) // the really used address +} + +func TestAdafruit2348Options(t *testing.T) { + // This is a general test, that options are applied in constructor by using the common WithBus() option and + // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". + // arrange & act + d := NewAdafruit2348Driver(newI2cTestAdaptor(), WithBus(2), WithAddress(0x45)) + // assert + assert.Equal(t, 2, d.GetBusOrDefault(1)) + assert.Equal(t, 0x45, d.GetAddressOrDefault(2)) +} + +func TestAdafruit2348SetDCMotorSpeed(t *testing.T) { + // arrange + d, a := initTestAdafruit2348WithStubbedAdaptor() + a.written = []byte{} // reset writes of former test + const ( + dcMotor = 1 + speed = 255 + ) + // act + err := d.SetDCMotorSpeed(dcMotor, speed) + // assert + assert.NoError(t, err) + assert.Equal(t, 8, len(a.written)) // detailed test, see "TestPCA9685SetPWM" +} + +func TestAdafruit2348SetDCMotorSpeedError(t *testing.T) { + // arrange + d, a := initTestAdafruit2348WithStubbedAdaptor() + a.i2cWriteImpl = func([]byte) (int, error) { + return 0, errors.New("write error") + } + // act & assert + assert.ErrorContains(t, d.SetDCMotorSpeed(1, 255), "write error") +} + +func TestAdafruit2348RunDCMotor(t *testing.T) { + // arrange + d, _ := initTestAdafruit2348WithStubbedAdaptor() + const dcMotor = 1 + // act & assert + assert.NoError(t, d.RunDCMotor(dcMotor, Adafruit2348Forward)) + assert.NoError(t, d.RunDCMotor(dcMotor, Adafruit2348Backward)) + assert.NoError(t, d.RunDCMotor(dcMotor, Adafruit2348Release)) +} + +func TestAdafruit2348RunDCMotorError(t *testing.T) { + // arrange + d, a := initTestAdafruit2348WithStubbedAdaptor() + a.i2cWriteImpl = func([]byte) (int, error) { + return 0, errors.New("write error") + } + const dcMotor = 1 + // act & assert + assert.ErrorContains(t, d.RunDCMotor(dcMotor, Adafruit2348Forward), "write error") + assert.ErrorContains(t, d.RunDCMotor(dcMotor, Adafruit2348Backward), "write error") + assert.ErrorContains(t, d.RunDCMotor(dcMotor, Adafruit2348Release), "write error") +} + +func TestAdafruit2348SetStepperMotorSpeed(t *testing.T) { + // arrange + d, _ := initTestAdafruit2348WithStubbedAdaptor() + const ( + stepperMotor = 1 + rpm = 30 + ) + // act & assert + assert.NoError(t, d.SetStepperMotorSpeed(stepperMotor, rpm)) + assert.Equal(t, 0.01, d.stepperMotors[stepperMotor].secPerStep) // 60/(revSteps*rpm), revSteps=200 +} + +func TestAdafruit2348StepperSingleStep(t *testing.T) { + // arrange + d, _ := initTestAdafruit2348WithStubbedAdaptor() + const ( + stepperMotor = 0 + steps = 50 + back = 1 + single = 0 + ) + // act + err := d.Step(stepperMotor, steps, back, single) + // assert + assert.NoError(t, err) +} + +func TestAdafruit2348StepperDoubleStep(t *testing.T) { + // arrange + d, _ := initTestAdafruit2348WithStubbedAdaptor() + const ( + stepperMotor = 0 + steps = 50 + back = 1 + double = 1 + ) + // act + err := d.Step(stepperMotor, steps, back, double) + // assert + assert.NoError(t, err) +} + +func TestAdafruit2348StepperInterleaveStep(t *testing.T) { + // arrange + d, _ := initTestAdafruit2348WithStubbedAdaptor() + const ( + stepperMotor = 0 + steps = 50 + back = 1 + interleave = 2 + ) + // act + err := d.Step(stepperMotor, steps, back, interleave) + // assert + assert.NoError(t, err) +} + +func TestAdafruit2348StepperMicroStep(t *testing.T) { + // arrange + d, _ := initTestAdafruit2348WithStubbedAdaptor() + const ( + stepperMotor = 0 + steps = 50 + back = 1 + micro = 3 + ) + // act + err := d.Step(stepperMotor, steps, back, micro) + // assert + assert.NoError(t, err) +} diff --git a/drivers/i2c/adafruit_driver.go b/drivers/i2c/adafruit_driver.go deleted file mode 100644 index 1d534ebfd..000000000 --- a/drivers/i2c/adafruit_driver.go +++ /dev/null @@ -1,564 +0,0 @@ -package i2c - -import ( - "errors" - "log" - "math" - "time" - - "gobot.io/x/gobot/v2" -) - -// AdafruitDirection declares a type for specification of the motor direction -type AdafruitDirection int - -// AdafruitStepStyle declares a type for specification of the stepper motor rotation -type AdafruitStepStyle int - -type adaFruitDCMotor struct { - pwmPin, in1Pin, in2Pin byte -} -type adaFruitStepperMotor struct { - pwmPinA, pwmPinB byte - ain1, ain2 byte - bin1, bin2 byte - secPerStep float64 - currentStep, stepCounter, revSteps int -} - -// AdafruitMotorHatDriver is a driver for the DC+Stepper Motor HAT from Adafruit. -// The HAT is a Raspberry Pi add-on that can drive up to 4 DC or 2 Stepper motors -// with full PWM speed control. It has a dedicated PWM driver chip onboard to -// control both motor direction and speed over I2C. -type AdafruitMotorHatDriver struct { - name string - connector Connector - motorHatConnection Connection - servoHatConnection Connection - Config - gobot.Commander - dcMotors []adaFruitDCMotor - stepperMotors []adaFruitStepperMotor -} - -var adafruitDebug = false // Set this to true to see debug output - -var ( - // Each Adafruit HAT must have a unique I2C address. The default address for - // the DC and Stepper Motor HAT is 0x60. The addresses of the Motor HATs can - // range from 0x60 to 0x80 for a total of 32 unique addresses. - // The base address for the Adafruit PWM-Servo HAT is 0x40. Please consult - // the Adafruit documentation for soldering and addressing stacked HATs. - motorHatAddress = 0x60 - servoHatAddress = 0x40 - stepperMicrosteps = 8 - stepperMicrostepCurve []int - step2coils = make(map[int][]int32) -) - -const ( - // Registers - _Mode1 = 0x00 - _Mode2 = 0x01 - _SubAdr1 = 0x02 - _SubAdr2 = 0x03 - _SubAdr3 = 0x04 - _Prescale = 0xFE - _LedZeroOnL = 0x06 - _LedZeroOnH = 0x07 - _LedZeroOffL = 0x08 - _LedZeroOffH = 0x09 - _AllLedOnL = 0xFA - _AllLedOnH = 0xFB - _AllLedOffL = 0xFC - _AllLedOffH = 0xFD - - // Bits - _Restart = 0x80 - _Sleep = 0x10 - _AllCall = 0x01 - _Invrt = 0x10 - _Outdrv = 0x04 -) - -const ( - AdafruitForward AdafruitDirection = iota // 0 - AdafruitBackward // 1 - AdafruitRelease // 2 -) - -const ( - AdafruitSingle AdafruitStepStyle = iota // 0 - AdafruitDouble // 1 - AdafruitInterleave // 2 - AdafruitMicrostep // 3 -) - -// NewAdafruitMotorHatDriver initializes the internal DCMotor and StepperMotor types. -// Again the Adafruit Motor Hat supports up to four DC motors and up to two stepper motors. -// Params: -// -// conn Connector - the Adaptor to use with this Driver -// -// Optional params: -// -// i2c.WithBus(int): bus to use with this driver -// i2c.WithAddress(int): address to use with this driver -func NewAdafruitMotorHatDriver(conn Connector, options ...func(Config)) *AdafruitMotorHatDriver { - var dc []adaFruitDCMotor - var st []adaFruitStepperMotor - for i := 0; i < 4; i++ { - switch { - case i == 0: - dc = append(dc, adaFruitDCMotor{pwmPin: 8, in1Pin: 10, in2Pin: 9}) - st = append(st, adaFruitStepperMotor{pwmPinA: 8, pwmPinB: 13, - ain1: 10, ain2: 9, bin1: 11, bin2: 12, revSteps: 200, secPerStep: 0.1}) - case i == 1: - dc = append(dc, adaFruitDCMotor{pwmPin: 13, in1Pin: 11, in2Pin: 12}) - st = append(st, adaFruitStepperMotor{pwmPinA: 2, pwmPinB: 7, - ain1: 4, ain2: 3, bin1: 5, bin2: 6, revSteps: 200, secPerStep: 0.1}) - case i == 2: - dc = append(dc, adaFruitDCMotor{pwmPin: 2, in1Pin: 4, in2Pin: 3}) - case i == 3: - dc = append(dc, adaFruitDCMotor{pwmPin: 7, in1Pin: 5, in2Pin: 6}) - } - } - - driver := &AdafruitMotorHatDriver{ - name: gobot.DefaultName("AdafruitMotorHat"), - connector: conn, - Config: NewConfig(), - Commander: gobot.NewCommander(), - dcMotors: dc, - stepperMotors: st, - } - - for _, option := range options { - option(driver) - } - - // TODO: add API funcs - return driver -} - -// SetMotorHatAddress sets the I2C address for the DC and Stepper Motor HAT. -// This addressing flexibility empowers "stacking" the HATs. -func (a *AdafruitMotorHatDriver) SetMotorHatAddress(addr int) (err error) { - motorHatAddress = addr - return -} - -// SetServoHatAddress sets the I2C address for the PWM-Servo Motor HAT. -// This addressing flexibility empowers "stacking" the HATs. -func (a *AdafruitMotorHatDriver) SetServoHatAddress(addr int) (err error) { - servoHatAddress = addr - return -} - -// Name identifies this driver object -func (a *AdafruitMotorHatDriver) Name() string { return a.name } - -// SetName sets nae for driver -func (a *AdafruitMotorHatDriver) SetName(n string) { a.name = n } - -// Connection identifies the particular adapter object -func (a *AdafruitMotorHatDriver) Connection() gobot.Connection { return a.connector.(gobot.Connection) } - -func (a *AdafruitMotorHatDriver) startDriver(connection Connection) (err error) { - if err = a.setAllPWM(connection, 0, 0); err != nil { - return - } - reg := byte(_Mode2) - val := byte(_Outdrv) - if _, err = connection.Write([]byte{reg, val}); err != nil { - return - } - reg = byte(_Mode1) - val = byte(_AllCall) - if _, err = connection.Write([]byte{reg, val}); err != nil { - return - } - time.Sleep(5 * time.Millisecond) - - // Read a byte from the I2C device. Note: no ability to read from a specified reg? - mode1 := []byte{0} - _, rerr := connection.Read(mode1) - if rerr != nil { - return rerr - } - if len(mode1) > 0 { - reg = byte(_Mode1) - val = mode1[0] & _Sleep - if _, err = connection.Write([]byte{reg, val}); err != nil { - return - } - time.Sleep(5 * time.Millisecond) - } - - return -} - -// Start initializes both I2C-addressable Adafruit Motor HAT drivers -func (a *AdafruitMotorHatDriver) Start() (err error) { - bus := a.GetBusOrDefault(a.connector.DefaultI2cBus()) - - err = a.startServoHat(bus) - if adafruitDebug && err != nil { - log.Printf("[adafruit_driver] start servohat error: %s\n", err) - } - - err = a.startMotorHat(bus) - if adafruitDebug && err != nil { - log.Printf("[adafruit_driver] start motorhat error: %s\n", err) - } - - return -} - -// startServoHat starts the Servo motors connection. -func (a *AdafruitMotorHatDriver) startServoHat(bus int) (err error) { - if a.servoHatConnection, err = a.connector.GetI2cConnection(servoHatAddress, bus); err != nil { - return - } - - if err = a.startDriver(a.servoHatConnection); err != nil { - return - } - - return -} - -// startMotorHat starts the DC motors connection. -func (a *AdafruitMotorHatDriver) startMotorHat(bus int) (err error) { - if a.motorHatConnection, err = a.connector.GetI2cConnection(motorHatAddress, bus); err != nil { - return - } - - if err = a.startDriver(a.motorHatConnection); err != nil { - return - } - - return -} - -// Halt returns true if devices is halted successfully -func (a *AdafruitMotorHatDriver) Halt() (err error) { return } - -// setPWM sets the start (on) and end (off) of the high-segment of the PWM pulse -// on the specific channel (pin). -func (a *AdafruitMotorHatDriver) setPWM(conn Connection, pin byte, on, off int32) (err error) { - // register and values to be written to that register - regVals := make(map[int][]byte) - regVals[0] = []byte{byte(_LedZeroOnL + 4*pin), byte(on & 0xff)} - regVals[1] = []byte{byte(_LedZeroOnH + 4*pin), byte(on >> 8)} - regVals[2] = []byte{byte(_LedZeroOffL + 4*pin), byte(off & 0xff)} - regVals[3] = []byte{byte(_LedZeroOffH + 4*pin), byte(off >> 8)} - for i := 0; i < len(regVals); i++ { - if _, err = conn.Write(regVals[i]); err != nil { - return - } - } - return -} - -// SetServoMotorFreq sets the frequency for the currently addressed PWM Servo HAT. -func (a *AdafruitMotorHatDriver) SetServoMotorFreq(freq float64) (err error) { - if err = a.setPWMFreq(a.servoHatConnection, freq); err != nil { - return - } - return -} - -// SetServoMotorPulse is a convenience function to specify the 'tick' value, -// between 0-4095, when the signal will turn on, and when it will turn off. -func (a *AdafruitMotorHatDriver) SetServoMotorPulse(channel byte, on, off int32) (err error) { - if err = a.setPWM(a.servoHatConnection, channel, on, off); err != nil { - return - } - return -} - -// setPWMFreq adjusts the PWM frequency which determines how many full -// pulses per second are generated by the integrated circuit. The frequency -// determines how "long" each pulse is in duration from start to finish, -// taking into account the high and low segments of the pulse. -func (a *AdafruitMotorHatDriver) setPWMFreq(conn Connection, freq float64) (err error) { - // 25MHz - preScaleVal := 25000000.0 - // 12-bit - preScaleVal /= 4096.0 - preScaleVal /= freq - preScaleVal -= 1.0 - preScale := math.Floor(preScaleVal + 0.5) - if adafruitDebug { - log.Printf("Setting PWM frequency to: %.2f Hz", freq) - log.Printf("Estimated pre-scale: %.2f", preScaleVal) - log.Printf("Final pre-scale: %.2f", preScale) - } - // default (and only) reads register 0 - oldMode := []byte{0} - _, err = conn.Read(oldMode) - if err != nil { - return - } - // sleep? - if len(oldMode) > 0 { - newMode := (oldMode[0] & 0x7F) | 0x10 - reg := byte(_Mode1) - if _, err = conn.Write([]byte{reg, newMode}); err != nil { - return - } - reg = byte(_Prescale) - val := byte(math.Floor(preScale)) - if _, err = conn.Write([]byte{reg, val}); err != nil { - return - } - reg = byte(_Mode1) - if _, err = conn.Write([]byte{reg, oldMode[0]}); err != nil { - return - } - time.Sleep(5 * time.Millisecond) - if _, err = conn.Write([]byte{reg, (oldMode[0] | 0x80)}); err != nil { - return - } - } - return -} - -// setAllPWM sets all PWM channels for the given address -func (a *AdafruitMotorHatDriver) setAllPWM(conn Connection, on, off int32) (err error) { - // register and values to be written to that register - regVals := make(map[int][]byte) - regVals[0] = []byte{byte(_AllLedOnL), byte(on & 0xff)} - regVals[1] = []byte{byte(_AllLedOnH), byte(on >> 8)} - regVals[2] = []byte{byte(_AllLedOffL), byte(off & 0xFF)} - regVals[3] = []byte{byte(_AllLedOffH), byte(off >> 8)} - for i := 0; i < len(regVals); i++ { - if _, err = conn.Write(regVals[i]); err != nil { - return - } - } - return -} - -func (a *AdafruitMotorHatDriver) setPin(conn Connection, pin byte, value int32) (err error) { - if value == 0 { - return a.setPWM(conn, pin, 0, 4096) - } - if value == 1 { - return a.setPWM(conn, pin, 4096, 0) - } - return errors.New("Invalid pin") -} - -// SetDCMotorSpeed will set the appropriate pins to run the specified DC motor -// for the given speed. -func (a *AdafruitMotorHatDriver) SetDCMotorSpeed(dcMotor int, speed int32) (err error) { - if err = a.setPWM(a.motorHatConnection, a.dcMotors[dcMotor].pwmPin, 0, speed*16); err != nil { - return - } - return -} - -// RunDCMotor will set the appropriate pins to run the specified DC motor for -// the given direction -func (a *AdafruitMotorHatDriver) RunDCMotor(dcMotor int, dir AdafruitDirection) (err error) { - - switch { - case dir == AdafruitForward: - if err = a.setPin(a.motorHatConnection, a.dcMotors[dcMotor].in2Pin, 0); err != nil { - return - } - if err = a.setPin(a.motorHatConnection, a.dcMotors[dcMotor].in1Pin, 1); err != nil { - return - } - case dir == AdafruitBackward: - if err = a.setPin(a.motorHatConnection, a.dcMotors[dcMotor].in1Pin, 0); err != nil { - return - } - if err = a.setPin(a.motorHatConnection, a.dcMotors[dcMotor].in2Pin, 1); err != nil { - return - } - case dir == AdafruitRelease: - if err = a.setPin(a.motorHatConnection, a.dcMotors[dcMotor].in1Pin, 0); err != nil { - return - } - if err = a.setPin(a.motorHatConnection, a.dcMotors[dcMotor].in2Pin, 0); err != nil { - return - } - } - return -} - -func (a *AdafruitMotorHatDriver) oneStep(motor int, dir AdafruitDirection, style AdafruitStepStyle) (steps int, err error) { - pwmA := 255 - pwmB := 255 - - // Determine the stepping procedure - switch { - case style == AdafruitSingle: - if (a.stepperMotors[motor].currentStep / (stepperMicrosteps / 2) % 2) != 0 { - // we're at an odd step - if dir == AdafruitForward { - a.stepperMotors[motor].currentStep += stepperMicrosteps / 2 - } else { - a.stepperMotors[motor].currentStep -= stepperMicrosteps / 2 - } - } else { - // go to next even step - if dir == AdafruitForward { - a.stepperMotors[motor].currentStep += stepperMicrosteps - } else { - a.stepperMotors[motor].currentStep -= stepperMicrosteps - } - } - case style == AdafruitDouble: - if (a.stepperMotors[motor].currentStep / (stepperMicrosteps / 2) % 2) == 0 { - // we're at an even step, weird - if dir == AdafruitForward { - a.stepperMotors[motor].currentStep += stepperMicrosteps / 2 - } else { - a.stepperMotors[motor].currentStep -= stepperMicrosteps / 2 - } - } else { - // go to next odd step - if dir == AdafruitForward { - a.stepperMotors[motor].currentStep += stepperMicrosteps - } else { - a.stepperMotors[motor].currentStep -= stepperMicrosteps - } - } - case style == AdafruitInterleave: - if dir == AdafruitForward { - a.stepperMotors[motor].currentStep += stepperMicrosteps / 2 - } else { - a.stepperMotors[motor].currentStep -= stepperMicrosteps / 2 - } - case style == AdafruitMicrostep: - if dir == AdafruitForward { - a.stepperMotors[motor].currentStep++ - } else { - a.stepperMotors[motor].currentStep-- - } - // go to next step and wrap around - a.stepperMotors[motor].currentStep += stepperMicrosteps * 4 - a.stepperMotors[motor].currentStep %= stepperMicrosteps * 4 - - pwmA = 0 - pwmB = 0 - currStep := a.stepperMotors[motor].currentStep - if currStep >= 0 && currStep < stepperMicrosteps { - pwmA = stepperMicrostepCurve[stepperMicrosteps-currStep] - pwmB = stepperMicrostepCurve[currStep] - } else if currStep >= stepperMicrosteps && currStep < stepperMicrosteps*2 { - pwmA = stepperMicrostepCurve[currStep-stepperMicrosteps] - pwmB = stepperMicrostepCurve[stepperMicrosteps*2-currStep] - } else if currStep >= stepperMicrosteps*2 && currStep < stepperMicrosteps*3 { - pwmA = stepperMicrostepCurve[stepperMicrosteps*3-currStep] - pwmB = stepperMicrostepCurve[currStep-stepperMicrosteps*2] - } else if currStep >= stepperMicrosteps*3 && currStep < stepperMicrosteps*4 { - pwmA = stepperMicrostepCurve[currStep-stepperMicrosteps*3] - pwmB = stepperMicrostepCurve[stepperMicrosteps*4-currStep] - } - } //switch - - //go to next 'step' and wrap around - a.stepperMotors[motor].currentStep += stepperMicrosteps * 4 - a.stepperMotors[motor].currentStep %= stepperMicrosteps * 4 - - //only really used for microstepping, otherwise always on! - if err = a.setPWM(a.motorHatConnection, a.stepperMotors[motor].pwmPinA, 0, int32(pwmA*16)); err != nil { - return - } - if err = a.setPWM(a.motorHatConnection, a.stepperMotors[motor].pwmPinB, 0, int32(pwmB*16)); err != nil { - return - } - var coils []int32 - currStep := a.stepperMotors[motor].currentStep - if style == AdafruitMicrostep { - switch { - case currStep >= 0 && currStep < stepperMicrosteps: - coils = []int32{1, 1, 0, 0} - case currStep >= stepperMicrosteps && currStep < stepperMicrosteps*2: - coils = []int32{0, 1, 1, 0} - case currStep >= stepperMicrosteps*2 && currStep < stepperMicrosteps*3: - coils = []int32{0, 0, 1, 1} - case currStep >= stepperMicrosteps*3 && currStep < stepperMicrosteps*4: - coils = []int32{1, 0, 0, 1} - } - } else { - // step-2-coils is initialized in init() - coils = step2coils[(currStep / (stepperMicrosteps / 2))] - } - if adafruitDebug { - log.Printf("[adafruit_driver] currStep: %d, index into step2coils: %d\n", - currStep, (currStep / (stepperMicrosteps / 2))) - log.Printf("[adafruit_driver] coils state = %v", coils) - } - if err = a.setPin(a.motorHatConnection, a.stepperMotors[motor].ain2, coils[0]); err != nil { - return - } - if err = a.setPin(a.motorHatConnection, a.stepperMotors[motor].bin1, coils[1]); err != nil { - return - } - if err = a.setPin(a.motorHatConnection, a.stepperMotors[motor].ain1, coils[2]); err != nil { - return - } - if err = a.setPin(a.motorHatConnection, a.stepperMotors[motor].bin2, coils[3]); err != nil { - return - } - return a.stepperMotors[motor].currentStep, nil -} - -// SetStepperMotorSpeed sets the seconds-per-step for the given Stepper Motor. -func (a *AdafruitMotorHatDriver) SetStepperMotorSpeed(stepperMotor int, rpm int) (err error) { - revSteps := a.stepperMotors[stepperMotor].revSteps - a.stepperMotors[stepperMotor].secPerStep = 60.0 / float64(revSteps*rpm) - a.stepperMotors[stepperMotor].stepCounter = 0 - return -} - -// Step will rotate the stepper motor the given number of steps, in the given direction and step style. -func (a *AdafruitMotorHatDriver) Step(motor, steps int, dir AdafruitDirection, style AdafruitStepStyle) (err error) { - secPerStep := a.stepperMotors[motor].secPerStep - latestStep := 0 - if style == AdafruitInterleave { - secPerStep = secPerStep / 2.0 - } - if style == AdafruitMicrostep { - secPerStep /= float64(stepperMicrosteps) - steps *= stepperMicrosteps - } - if adafruitDebug { - log.Printf("[adafruit_driver] %f seconds per step", secPerStep) - } - for i := 0; i < steps; i++ { - if latestStep, err = a.oneStep(motor, dir, style); err != nil { - return - } - time.Sleep(time.Duration(secPerStep) * time.Second) - } - // As documented in the Adafruit python driver: - // This is an edge case, if we are in between full steps, keep going to end on a full step - if style == AdafruitMicrostep { - for latestStep != 0 && latestStep != stepperMicrosteps { - if latestStep, err = a.oneStep(motor, dir, style); err != nil { - return - } - time.Sleep(time.Duration(secPerStep) * time.Second) - } - } - return -} - -func init() { - stepperMicrostepCurve = []int{0, 50, 98, 142, 180, 212, 236, 250, 255} - step2coils[0] = []int32{1, 0, 0, 0} - step2coils[1] = []int32{1, 1, 0, 0} - step2coils[2] = []int32{0, 1, 0, 0} - step2coils[3] = []int32{0, 1, 1, 0} - step2coils[4] = []int32{0, 0, 1, 0} - step2coils[5] = []int32{0, 0, 1, 1} - step2coils[6] = []int32{0, 0, 0, 1} - step2coils[7] = []int32{1, 0, 0, 1} -} diff --git a/drivers/i2c/adafruit_driver_test.go b/drivers/i2c/adafruit_driver_test.go deleted file mode 100644 index 4f2bbd6b2..000000000 --- a/drivers/i2c/adafruit_driver_test.go +++ /dev/null @@ -1,245 +0,0 @@ -package i2c - -import ( - "errors" - "strings" - "testing" - - "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" -) - -// this ensures that the implementation implements the gobot.Driver interface -var _ gobot.Driver = (*AdafruitMotorHatDriver)(nil) - -// --------- HELPERS -func initTestAdafruitMotorHatDriver() (driver *AdafruitMotorHatDriver) { - driver, _ = initTestAdafruitMotorHatDriverWithStubbedAdaptor() - return -} - -func initTestAdafruitMotorHatDriverWithStubbedAdaptor() (*AdafruitMotorHatDriver, *i2cTestAdaptor) { - adaptor := newI2cTestAdaptor() - return NewAdafruitMotorHatDriver(adaptor), adaptor -} - -// --------- TESTS -func TestNewAdafruitMotorHatDriver(t *testing.T) { - var di interface{} = NewAdafruitMotorHatDriver(newI2cTestAdaptor()) - d, ok := di.(*AdafruitMotorHatDriver) - if !ok { - t.Errorf("AdafruitMotorHatDriver() should have returned a *AdafruitMotorHatDriver") - } - gobottest.Assert(t, strings.HasPrefix(d.Name(), "AdafruitMotorHat"), true) -} - -// Methods -func TestAdafruitMotorHatDriverStart(t *testing.T) { - ada, _ := initTestAdafruitMotorHatDriverWithStubbedAdaptor() - gobottest.Refute(t, ada.Connection(), nil) - gobottest.Assert(t, ada.Start(), nil) -} - -func TestAdafruitMotorHatDriverStartWriteError(t *testing.T) { - d, adaptor := initTestAdafruitMotorHatDriverWithStubbedAdaptor() - adaptor.i2cWriteImpl = func([]byte) (int, error) { - return 0, errors.New("write error") - } - gobottest.Assert(t, d.Start(), errors.New("write error")) -} - -func TestAdafruitMotorHatDriverStartReadError(t *testing.T) { - d, adaptor := initTestAdafruitMotorHatDriverWithStubbedAdaptor() - adaptor.i2cReadImpl = func([]byte) (int, error) { - return 0, errors.New("read error") - } - gobottest.Assert(t, d.Start(), errors.New("read error")) -} - -func TestAdafruitMotorHatDriverStartConnectError(t *testing.T) { - d, adaptor := initTestAdafruitMotorHatDriverWithStubbedAdaptor() - adaptor.Testi2cConnectErr(true) - gobottest.Assert(t, d.Start(), errors.New("Invalid i2c connection")) -} - -func TestAdafruitMotorHatDriverHalt(t *testing.T) { - ada, _ := initTestAdafruitMotorHatDriverWithStubbedAdaptor() - - gobottest.Assert(t, ada.Halt(), nil) -} - -func TestSetHatAddresses(t *testing.T) { - ada, _ := initTestAdafruitMotorHatDriverWithStubbedAdaptor() - - motorHatAddr := 0x61 - servoHatAddr := 0x41 - gobottest.Assert(t, ada.SetMotorHatAddress(motorHatAddr), nil) - gobottest.Assert(t, ada.SetServoHatAddress(servoHatAddr), nil) -} - -func TestAdafruitMotorHatDriverSetServoMotorFreq(t *testing.T) { - ada, _ := initTestAdafruitMotorHatDriverWithStubbedAdaptor() - - gobottest.Assert(t, ada.Start(), nil) - - freq := 60.0 - err := ada.SetServoMotorFreq(freq) - gobottest.Assert(t, err, nil) -} - -func TestAdafruitMotorHatDriverSetServoMotorFreqError(t *testing.T) { - ada, a := initTestAdafruitMotorHatDriverWithStubbedAdaptor() - - gobottest.Assert(t, ada.Start(), nil) - a.i2cWriteImpl = func([]byte) (int, error) { - return 0, errors.New("write error") - } - - freq := 60.0 - gobottest.Assert(t, ada.SetServoMotorFreq(freq), errors.New("write error")) -} - -func TestAdafruitMotorHatDriverSetServoMotorPulse(t *testing.T) { - ada, _ := initTestAdafruitMotorHatDriverWithStubbedAdaptor() - - gobottest.Assert(t, ada.Start(), nil) - - var channel byte = 7 - var on int32 = 1234 - var off int32 = 4321 - err := ada.SetServoMotorPulse(channel, on, off) - gobottest.Assert(t, err, nil) -} - -func TestAdafruitMotorHatDriverSetServoMotorPulseError(t *testing.T) { - ada, a := initTestAdafruitMotorHatDriverWithStubbedAdaptor() - - gobottest.Assert(t, ada.Start(), nil) - a.i2cWriteImpl = func([]byte) (int, error) { - return 0, errors.New("write error") - } - - var channel byte = 7 - var on int32 = 1234 - var off int32 = 4321 - gobottest.Assert(t, ada.SetServoMotorPulse(channel, on, off), errors.New("write error")) -} - -func TestAdafruitMotorHatDriverSetDCMotorSpeed(t *testing.T) { - ada, _ := initTestAdafruitMotorHatDriverWithStubbedAdaptor() - - gobottest.Assert(t, ada.Start(), nil) - - dcMotor := 1 - var speed int32 = 255 - err := ada.SetDCMotorSpeed(dcMotor, speed) - gobottest.Assert(t, err, nil) -} - -func TestAdafruitMotorHatDriverSetDCMotorSpeedError(t *testing.T) { - ada, a := initTestAdafruitMotorHatDriverWithStubbedAdaptor() - - gobottest.Assert(t, ada.Start(), nil) - a.i2cWriteImpl = func([]byte) (int, error) { - return 0, errors.New("write error") - } - - gobottest.Assert(t, ada.SetDCMotorSpeed(1, 255), errors.New("write error")) -} - -func TestAdafruitMotorHatDriverRunDCMotor(t *testing.T) { - ada, _ := initTestAdafruitMotorHatDriverWithStubbedAdaptor() - - gobottest.Assert(t, ada.Start(), nil) - - dcMotor := 1 - gobottest.Assert(t, ada.RunDCMotor(dcMotor, AdafruitForward), nil) - gobottest.Assert(t, ada.RunDCMotor(dcMotor, AdafruitBackward), nil) - gobottest.Assert(t, ada.RunDCMotor(dcMotor, AdafruitRelease), nil) -} - -func TestAdafruitMotorHatDriverRunDCMotorError(t *testing.T) { - ada, a := initTestAdafruitMotorHatDriverWithStubbedAdaptor() - gobottest.Assert(t, ada.Start(), nil) - a.i2cWriteImpl = func([]byte) (int, error) { - return 0, errors.New("write error") - } - - dcMotor := 1 - gobottest.Assert(t, ada.RunDCMotor(dcMotor, AdafruitForward), errors.New("write error")) - gobottest.Assert(t, ada.RunDCMotor(dcMotor, AdafruitBackward), errors.New("write error")) - gobottest.Assert(t, ada.RunDCMotor(dcMotor, AdafruitRelease), errors.New("write error")) -} - -func TestAdafruitMotorHatDriverSetStepperMotorSpeed(t *testing.T) { - ada, _ := initTestAdafruitMotorHatDriverWithStubbedAdaptor() - - gobottest.Assert(t, ada.Start(), nil) - - stepperMotor := 1 - rpm := 30 - gobottest.Assert(t, ada.SetStepperMotorSpeed(stepperMotor, rpm), nil) -} - -func TestAdafruitMotorHatDriverStepperMicroStep(t *testing.T) { - ada, _ := initTestAdafruitMotorHatDriverWithStubbedAdaptor() - - gobottest.Assert(t, ada.Start(), nil) - - // NOTE: not using the direction and style constants to prevent importing - // the i2c package - stepperMotor := 0 - steps := 50 - err := ada.Step(stepperMotor, steps, 1, 3) - gobottest.Assert(t, err, nil) -} - -func TestAdafruitMotorHatDriverStepperSingleStep(t *testing.T) { - ada, _ := initTestAdafruitMotorHatDriverWithStubbedAdaptor() - - gobottest.Assert(t, ada.Start(), nil) - - // NOTE: not using the direction and style constants to prevent importing - // the i2c package - stepperMotor := 0 - steps := 50 - err := ada.Step(stepperMotor, steps, 1, 0) - gobottest.Assert(t, err, nil) -} - -func TestAdafruitMotorHatDriverStepperDoubleStep(t *testing.T) { - ada, _ := initTestAdafruitMotorHatDriverWithStubbedAdaptor() - - gobottest.Assert(t, ada.Start(), nil) - - // NOTE: not using the direction and style constants to prevent importing - // the i2c package - stepperMotor := 0 - steps := 50 - err := ada.Step(stepperMotor, steps, 1, 1) - gobottest.Assert(t, err, nil) -} - -func TestAdafruitMotorHatDriverStepperInterleaveStep(t *testing.T) { - ada, _ := initTestAdafruitMotorHatDriverWithStubbedAdaptor() - - gobottest.Assert(t, ada.Start(), nil) - - // NOTE: not using the direction and style constants to prevent importing - // the i2c package - stepperMotor := 0 - steps := 50 - err := ada.Step(stepperMotor, steps, 1, 2) - gobottest.Assert(t, err, nil) -} - -func TestAdafruitMotorHatDriverSetName(t *testing.T) { - d := initTestAdafruitMotorHatDriver() - d.SetName("TESTME") - gobottest.Assert(t, d.Name(), "TESTME") -} - -func TestAdafruitMotorHatDriverOptions(t *testing.T) { - d := NewAdafruitMotorHatDriver(newI2cTestAdaptor(), WithBus(2)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) -} diff --git a/drivers/i2c/ads1x15_driver.go b/drivers/i2c/ads1x15_driver.go index 1645f20ec..487dcb16e 100644 --- a/drivers/i2c/ads1x15_driver.go +++ b/drivers/i2c/ads1x15_driver.go @@ -1,13 +1,12 @@ package i2c import ( + "fmt" "log" "math" "sort" "strconv" "time" - - "fmt" ) const ads1x15DefaultAddress = 0x48 diff --git a/drivers/i2c/ads1x15_driver_1015_test.go b/drivers/i2c/ads1x15_driver_1015_test.go index 8e009bcd6..be88c09ee 100644 --- a/drivers/i2c/ads1x15_driver_1015_test.go +++ b/drivers/i2c/ads1x15_driver_1015_test.go @@ -5,7 +5,7 @@ import ( "strings" "testing" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) func initTestADS1015DriverWithStubbedAdaptor() (*ADS1x15Driver, *i2cTestAdaptor) { @@ -23,11 +23,11 @@ func TestNewADS1015Driver(t *testing.T) { if !ok { t.Errorf("NewADS1015Driver() should have returned a *ADS1x15Driver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "ADS1015"), true) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "ADS1015")) for i := 0; i <= 3; i++ { - gobottest.Assert(t, d.channelCfgs[i].gain, 1) - gobottest.Assert(t, d.channelCfgs[i].dataRate, 1600) + assert.Equal(t, 1, d.channelCfgs[i].gain) + assert.Equal(t, 1600, d.channelCfgs[i].dataRate) } } @@ -35,10 +35,10 @@ func TestADS1015Options(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option and // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". d := NewADS1015Driver(newI2cTestAdaptor(), WithBus(2), WithADS1x15Gain(2), WithADS1x15DataRate(920)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) + assert.Equal(t, 2, d.GetBusOrDefault(1)) for i := 0; i <= 3; i++ { - gobottest.Assert(t, d.channelCfgs[i].gain, 2) - gobottest.Assert(t, d.channelCfgs[i].dataRate, 920) + assert.Equal(t, 2, d.channelCfgs[i].gain) + assert.Equal(t, 920, d.channelCfgs[i].dataRate) } } @@ -46,7 +46,7 @@ func TestADS1015WithADS1x15BestGainForVoltage(t *testing.T) { d, _ := initTestADS1015DriverWithStubbedAdaptor() WithADS1x15BestGainForVoltage(1.01)(d) for i := 0; i <= 3; i++ { - gobottest.Assert(t, d.channelCfgs[i].gain, 3) + assert.Equal(t, 3, d.channelCfgs[i].gain) } } @@ -56,10 +56,10 @@ func TestADS1015WithADS1x15ChannelBestGainForVoltage(t *testing.T) { WithADS1x15ChannelBestGainForVoltage(1, 2.5)(d) WithADS1x15ChannelBestGainForVoltage(2, 3.3)(d) WithADS1x15ChannelBestGainForVoltage(3, 5.0)(d) - gobottest.Assert(t, d.channelCfgs[0].gain, 3) - gobottest.Assert(t, d.channelCfgs[1].gain, 1) - gobottest.Assert(t, d.channelCfgs[2].gain, 1) - gobottest.Assert(t, d.channelCfgs[3].gain, 0) + assert.Equal(t, 3, d.channelCfgs[0].gain) + assert.Equal(t, 1, d.channelCfgs[1].gain) + assert.Equal(t, 1, d.channelCfgs[2].gain) + assert.Equal(t, 0, d.channelCfgs[3].gain) } func TestADS1015AnalogRead(t *testing.T) { @@ -72,39 +72,39 @@ func TestADS1015AnalogRead(t *testing.T) { } val, err := d.AnalogRead("0") - gobottest.Assert(t, val, 32767) - gobottest.Assert(t, err, nil) + assert.Equal(t, 32767, val) + assert.NoError(t, err) val, err = d.AnalogRead("1") - gobottest.Assert(t, val, 32767) - gobottest.Assert(t, err, nil) + assert.Equal(t, 32767, val) + assert.NoError(t, err) val, err = d.AnalogRead("2") - gobottest.Assert(t, val, 32767) - gobottest.Assert(t, err, nil) + assert.Equal(t, 32767, val) + assert.NoError(t, err) val, err = d.AnalogRead("3") - gobottest.Assert(t, val, 32767) - gobottest.Assert(t, err, nil) + assert.Equal(t, 32767, val) + assert.NoError(t, err) val, err = d.AnalogRead("0-1") - gobottest.Assert(t, val, 32767) - gobottest.Assert(t, err, nil) + assert.Equal(t, 32767, val) + assert.NoError(t, err) val, err = d.AnalogRead("0-3") - gobottest.Assert(t, val, 32767) - gobottest.Assert(t, err, nil) + assert.Equal(t, 32767, val) + assert.NoError(t, err) val, err = d.AnalogRead("1-3") - gobottest.Assert(t, val, 32767) - gobottest.Assert(t, err, nil) + assert.Equal(t, 32767, val) + assert.NoError(t, err) val, err = d.AnalogRead("2-3") - gobottest.Assert(t, val, 32767) - gobottest.Assert(t, err, nil) + assert.Equal(t, 32767, val) + assert.NoError(t, err) _, err = d.AnalogRead("3-2") - gobottest.Refute(t, err.Error(), nil) + assert.NotNil(t, err.Error()) } func TestADS1x15AnalogReadError(t *testing.T) { @@ -115,14 +115,14 @@ func TestADS1x15AnalogReadError(t *testing.T) { } _, err := d.AnalogRead("0") - gobottest.Assert(t, err, errors.New("read error")) + assert.ErrorContains(t, err, "read error") } func TestADS1x15AnalogReadInvalidPin(t *testing.T) { d, _ := initTestADS1015DriverWithStubbedAdaptor() _, err := d.AnalogRead("99") - gobottest.Assert(t, err, errors.New("Invalid channel (99), must be between 0 and 3")) + assert.ErrorContains(t, err, "Invalid channel (99), must be between 0 and 3") } func TestADS1x15AnalogReadWriteError(t *testing.T) { @@ -133,41 +133,41 @@ func TestADS1x15AnalogReadWriteError(t *testing.T) { } _, err := d.AnalogRead("0") - gobottest.Assert(t, err, errors.New("write error")) + assert.ErrorContains(t, err, "write error") _, err = d.AnalogRead("0-1") - gobottest.Assert(t, err, errors.New("write error")) + assert.ErrorContains(t, err, "write error") _, err = d.AnalogRead("2-3") - gobottest.Assert(t, err, errors.New("write error")) + assert.ErrorContains(t, err, "write error") } func TestADS1x15ReadInvalidChannel(t *testing.T) { d, _ := initTestADS1015DriverWithStubbedAdaptor() _, err := d.Read(9, 1, 1600) - gobottest.Assert(t, err, errors.New("Invalid channel (9), must be between 0 and 3")) + assert.ErrorContains(t, err, "Invalid channel (9), must be between 0 and 3") } func TestADS1x15ReadInvalidGain(t *testing.T) { d, _ := initTestADS1015DriverWithStubbedAdaptor() _, err := d.Read(0, 8, 1600) - gobottest.Assert(t, err, errors.New("Gain (8) must be one of: [0 1 2 3 4 5 6 7]")) + assert.ErrorContains(t, err, "Gain (8) must be one of: [0 1 2 3 4 5 6 7]") } func TestADS1x15ReadInvalidDataRate(t *testing.T) { d, _ := initTestADS1015DriverWithStubbedAdaptor() _, err := d.Read(0, 1, 321) - gobottest.Assert(t, err, errors.New("Invalid data rate (321). Accepted values: [128 250 490 920 1600 2400 3300]")) + assert.ErrorContains(t, err, "Invalid data rate (321). Accepted values: [128 250 490 920 1600 2400 3300]") } func TestADS1x15ReadDifferenceInvalidChannel(t *testing.T) { d, _ := initTestADS1015DriverWithStubbedAdaptor() _, err := d.ReadDifference(9, 1, 1600) - gobottest.Assert(t, err, errors.New("Invalid channel (9), must be between 0 and 3")) + assert.ErrorContains(t, err, "Invalid channel (9), must be between 0 and 3") } func TestADS1015_rawRead(t *testing.T) { @@ -177,7 +177,7 @@ func TestADS1015_rawRead(t *testing.T) { // * read config register (16 bit, MSByte first) and wait for bit 15 is set // * read conversion register (16 bit, MSByte first) for the value // * apply two's complement converter, relates to one digit resolution (1/2^15), voltage multiplier - var tests = map[string]struct { + tests := map[string]struct { input []uint8 gain int dataRate int @@ -269,16 +269,16 @@ func TestADS1015_rawRead(t *testing.T) { // act got, err := d.rawRead(channel, channelOffset, tt.gain, tt.dataRate) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, got, tt.want) - gobottest.Assert(t, numCallsRead, 3) - gobottest.Assert(t, len(a.written), 6) - gobottest.Assert(t, a.written[0], uint8(ads1x15PointerConfig)) - gobottest.Assert(t, a.written[1], tt.wantConfig[0]) // MSByte: OS, MUX, PGA, MODE - gobottest.Assert(t, a.written[2], tt.wantConfig[1]) // LSByte: DR, COMP_* - gobottest.Assert(t, a.written[3], uint8(ads1x15PointerConfig)) // first check for no conversion - gobottest.Assert(t, a.written[4], uint8(ads1x15PointerConfig)) // second check for no conversion - gobottest.Assert(t, a.written[5], uint8(ads1x15PointerConversion)) + assert.NoError(t, err) + assert.Equal(t, tt.want, got) + assert.Equal(t, 3, numCallsRead) + assert.Equal(t, 6, len(a.written)) + assert.Equal(t, uint8(ads1x15PointerConfig), a.written[0]) + assert.Equal(t, tt.wantConfig[0], a.written[1]) // MSByte: OS, MUX, PGA, MODE + assert.Equal(t, tt.wantConfig[1], a.written[2]) // LSByte: DR, COMP_* + assert.Equal(t, uint8(ads1x15PointerConfig), a.written[3]) // first check for no conversion + assert.Equal(t, uint8(ads1x15PointerConfig), a.written[4]) // second check for no conversion + assert.Equal(t, uint8(ads1x15PointerConversion), a.written[5]) }) } } diff --git a/drivers/i2c/ads1x15_driver_1115_test.go b/drivers/i2c/ads1x15_driver_1115_test.go index 617d39fa7..03c7e4b81 100644 --- a/drivers/i2c/ads1x15_driver_1115_test.go +++ b/drivers/i2c/ads1x15_driver_1115_test.go @@ -5,7 +5,7 @@ import ( "strings" "testing" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) func initTestADS1115DriverWithStubbedAdaptor() (*ADS1x15Driver, *i2cTestAdaptor) { @@ -23,11 +23,11 @@ func TestNewADS1115Driver(t *testing.T) { if !ok { t.Errorf("NewADS1115Driver() should have returned a *ADS1x15Driver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "ADS1115"), true) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "ADS1115")) for i := 0; i <= 3; i++ { - gobottest.Assert(t, d.channelCfgs[i].gain, 1) - gobottest.Assert(t, d.channelCfgs[i].dataRate, 128) + assert.Equal(t, 1, d.channelCfgs[i].gain) + assert.Equal(t, 128, d.channelCfgs[i].dataRate) } } @@ -35,10 +35,10 @@ func TestADS1115Options(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option and // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". d := NewADS1115Driver(newI2cTestAdaptor(), WithBus(2), WithADS1x15Gain(2), WithADS1x15DataRate(860)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) + assert.Equal(t, 2, d.GetBusOrDefault(1)) for i := 0; i <= 3; i++ { - gobottest.Assert(t, d.channelCfgs[i].gain, 2) - gobottest.Assert(t, d.channelCfgs[i].dataRate, 860) + assert.Equal(t, 2, d.channelCfgs[i].gain) + assert.Equal(t, 860, d.channelCfgs[i].dataRate) } } @@ -46,7 +46,7 @@ func TestADS1115WithADS1x15BestGainForVoltage(t *testing.T) { d, _ := initTestADS1115DriverWithStubbedAdaptor() WithADS1x15BestGainForVoltage(1.01)(d) for i := 0; i <= 3; i++ { - gobottest.Assert(t, d.channelCfgs[i].gain, 3) + assert.Equal(t, 3, d.channelCfgs[i].gain) } } @@ -56,10 +56,10 @@ func TestADS1115WithADS1x15ChannelBestGainForVoltage(t *testing.T) { WithADS1x15ChannelBestGainForVoltage(1, 2.5)(d) WithADS1x15ChannelBestGainForVoltage(2, 3.3)(d) WithADS1x15ChannelBestGainForVoltage(3, 5.0)(d) - gobottest.Assert(t, d.channelCfgs[0].gain, 3) - gobottest.Assert(t, d.channelCfgs[1].gain, 1) - gobottest.Assert(t, d.channelCfgs[2].gain, 1) - gobottest.Assert(t, d.channelCfgs[3].gain, 0) + assert.Equal(t, 3, d.channelCfgs[0].gain) + assert.Equal(t, 1, d.channelCfgs[1].gain) + assert.Equal(t, 1, d.channelCfgs[2].gain) + assert.Equal(t, 0, d.channelCfgs[3].gain) } func TestADS1115AnalogRead(t *testing.T) { @@ -72,39 +72,39 @@ func TestADS1115AnalogRead(t *testing.T) { } val, err := d.AnalogRead("0") - gobottest.Assert(t, val, 32767) - gobottest.Assert(t, err, nil) + assert.Equal(t, 32767, val) + assert.NoError(t, err) val, err = d.AnalogRead("1") - gobottest.Assert(t, val, 32767) - gobottest.Assert(t, err, nil) + assert.Equal(t, 32767, val) + assert.NoError(t, err) val, err = d.AnalogRead("2") - gobottest.Assert(t, val, 32767) - gobottest.Assert(t, err, nil) + assert.Equal(t, 32767, val) + assert.NoError(t, err) val, err = d.AnalogRead("3") - gobottest.Assert(t, val, 32767) - gobottest.Assert(t, err, nil) + assert.Equal(t, 32767, val) + assert.NoError(t, err) val, err = d.AnalogRead("0-1") - gobottest.Assert(t, val, 32767) - gobottest.Assert(t, err, nil) + assert.Equal(t, 32767, val) + assert.NoError(t, err) val, err = d.AnalogRead("0-3") - gobottest.Assert(t, val, 32767) - gobottest.Assert(t, err, nil) + assert.Equal(t, 32767, val) + assert.NoError(t, err) val, err = d.AnalogRead("1-3") - gobottest.Assert(t, val, 32767) - gobottest.Assert(t, err, nil) + assert.Equal(t, 32767, val) + assert.NoError(t, err) val, err = d.AnalogRead("2-3") - gobottest.Assert(t, val, 32767) - gobottest.Assert(t, err, nil) + assert.Equal(t, 32767, val) + assert.NoError(t, err) _, err = d.AnalogRead("3-2") - gobottest.Refute(t, err.Error(), nil) + assert.NotNil(t, err.Error()) } func TestADS1115AnalogReadError(t *testing.T) { @@ -115,14 +115,14 @@ func TestADS1115AnalogReadError(t *testing.T) { } _, err := d.AnalogRead("0") - gobottest.Assert(t, err, errors.New("read error")) + assert.ErrorContains(t, err, "read error") } func TestADS1115AnalogReadInvalidPin(t *testing.T) { d, _ := initTestADS1115DriverWithStubbedAdaptor() _, err := d.AnalogRead("98") - gobottest.Assert(t, err, errors.New("Invalid channel (98), must be between 0 and 3")) + assert.ErrorContains(t, err, "Invalid channel (98), must be between 0 and 3") } func TestADS1115AnalogReadWriteError(t *testing.T) { @@ -133,41 +133,41 @@ func TestADS1115AnalogReadWriteError(t *testing.T) { } _, err := d.AnalogRead("0") - gobottest.Assert(t, err, errors.New("write error")) + assert.ErrorContains(t, err, "write error") _, err = d.AnalogRead("0-1") - gobottest.Assert(t, err, errors.New("write error")) + assert.ErrorContains(t, err, "write error") _, err = d.AnalogRead("2-3") - gobottest.Assert(t, err, errors.New("write error")) + assert.ErrorContains(t, err, "write error") } func TestADS1115ReadInvalidChannel(t *testing.T) { d, _ := initTestADS1115DriverWithStubbedAdaptor() _, err := d.Read(7, 1, 1600) - gobottest.Assert(t, err, errors.New("Invalid channel (7), must be between 0 and 3")) + assert.ErrorContains(t, err, "Invalid channel (7), must be between 0 and 3") } func TestADS1115ReadInvalidGain(t *testing.T) { d, _ := initTestADS1115DriverWithStubbedAdaptor() _, err := d.Read(0, 21, 1600) - gobottest.Assert(t, err, errors.New("Gain (21) must be one of: [0 1 2 3 4 5 6 7]")) + assert.ErrorContains(t, err, "Gain (21) must be one of: [0 1 2 3 4 5 6 7]") } func TestADS1115ReadInvalidDataRate(t *testing.T) { d, _ := initTestADS1115DriverWithStubbedAdaptor() _, err := d.Read(0, 1, 678) - gobottest.Assert(t, err, errors.New("Invalid data rate (678). Accepted values: [8 16 32 64 128 250 475 860]")) + assert.ErrorContains(t, err, "Invalid data rate (678). Accepted values: [8 16 32 64 128 250 475 860]") } func TestADS1115ReadDifferenceInvalidChannel(t *testing.T) { d, _ := initTestADS1115DriverWithStubbedAdaptor() _, err := d.ReadDifference(5, 1, 1600) - gobottest.Assert(t, err, errors.New("Invalid channel (5), must be between 0 and 3")) + assert.ErrorContains(t, err, "Invalid channel (5), must be between 0 and 3") } func TestADS1115_rawRead(t *testing.T) { @@ -177,7 +177,7 @@ func TestADS1115_rawRead(t *testing.T) { // * read config register (16 bit, MSByte first) and wait for bit 15 is set // * read conversion register (16 bit, MSByte first) for the value // * apply two's complement converter, relates to one digit resolution (1/2^15), voltage multiplier - var tests = map[string]struct { + tests := map[string]struct { input []uint8 gain int dataRate int @@ -269,16 +269,16 @@ func TestADS1115_rawRead(t *testing.T) { // act got, err := d.rawRead(channel, channelOffset, tt.gain, tt.dataRate) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, got, tt.want) - gobottest.Assert(t, numCallsRead, 3) - gobottest.Assert(t, len(a.written), 6) - gobottest.Assert(t, a.written[0], uint8(ads1x15PointerConfig)) - gobottest.Assert(t, a.written[1], tt.wantConfig[0]) // MSByte: OS, MUX, PGA, MODE - gobottest.Assert(t, a.written[2], tt.wantConfig[1]) // LSByte: DR, COMP_* - gobottest.Assert(t, a.written[3], uint8(ads1x15PointerConfig)) // first check for no conversion - gobottest.Assert(t, a.written[4], uint8(ads1x15PointerConfig)) // second check for no conversion - gobottest.Assert(t, a.written[5], uint8(ads1x15PointerConversion)) + assert.NoError(t, err) + assert.Equal(t, tt.want, got) + assert.Equal(t, 3, numCallsRead) + assert.Equal(t, 6, len(a.written)) + assert.Equal(t, uint8(ads1x15PointerConfig), a.written[0]) + assert.Equal(t, tt.wantConfig[0], a.written[1]) // MSByte: OS, MUX, PGA, MODE + assert.Equal(t, tt.wantConfig[1], a.written[2]) // LSByte: DR, COMP_* + assert.Equal(t, uint8(ads1x15PointerConfig), a.written[3]) // first check for no conversion + assert.Equal(t, uint8(ads1x15PointerConfig), a.written[4]) // second check for no conversion + assert.Equal(t, uint8(ads1x15PointerConversion), a.written[5]) }) } } diff --git a/drivers/i2c/ads1x15_driver_test.go b/drivers/i2c/ads1x15_driver_test.go index 948a36597..d88f46cab 100644 --- a/drivers/i2c/ads1x15_driver_test.go +++ b/drivers/i2c/ads1x15_driver_test.go @@ -1,12 +1,11 @@ package i2c import ( - "errors" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" "gobot.io/x/gobot/v2/drivers/aio" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -16,7 +15,7 @@ var _ gobot.Driver = (*ADS1x15Driver)(nil) // that supports the AnalogReader interface var _ aio.AnalogReader = (*ADS1x15Driver)(nil) -func initTestADS1x15DriverWithStubbedAdaptor() (*ADS1x15Driver, *i2cTestAdaptor) { +func initTestADS1x15DriverWithStubbedAdaptor() (*ADS1x15Driver, *i2cTestAdaptor) { //nolint:unparam // keep for tests a := newI2cTestAdaptor() const defaultDataRate = 3 dataRates := map[int]uint16{defaultDataRate: 0x0003} @@ -48,8 +47,8 @@ func TestADS1x15CommandsReadDifferenceWithDefaults(t *testing.T) { // act result := d.Command("ReadDifferenceWithDefaults")(ads1x15TestChannel) // assert - gobottest.Assert(t, result.(map[string]interface{})["err"], nil) - gobottest.Assert(t, result.(map[string]interface{})["val"], -4.096) + assert.Nil(t, result.(map[string]interface{})["err"]) + assert.Equal(t, -4.096, result.(map[string]interface{})["val"]) } func TestADS1x15CommandsReadDifference(t *testing.T) { @@ -58,8 +57,8 @@ func TestADS1x15CommandsReadDifference(t *testing.T) { // act result := d.Command("ReadDifference")(ads1x15TestChannelGainDataRate) // assert - gobottest.Assert(t, result.(map[string]interface{})["err"], nil) - gobottest.Assert(t, result.(map[string]interface{})["val"], -2.048) + assert.Nil(t, result.(map[string]interface{})["err"]) + assert.Equal(t, -2.048, result.(map[string]interface{})["val"]) } func TestADS1x15CommandsReadWithDefaults(t *testing.T) { @@ -68,8 +67,8 @@ func TestADS1x15CommandsReadWithDefaults(t *testing.T) { // act result := d.Command("ReadWithDefaults")(ads1x15TestChannel) // assert - gobottest.Assert(t, result.(map[string]interface{})["err"], nil) - gobottest.Assert(t, result.(map[string]interface{})["val"], -4.096) + assert.Nil(t, result.(map[string]interface{})["err"]) + assert.Equal(t, -4.096, result.(map[string]interface{})["val"]) } func TestADS1x15CommandsRead(t *testing.T) { @@ -78,8 +77,8 @@ func TestADS1x15CommandsRead(t *testing.T) { // act result := d.Command("Read")(ads1x15TestChannelGainDataRate) // assert - gobottest.Assert(t, result.(map[string]interface{})["err"], nil) - gobottest.Assert(t, result.(map[string]interface{})["val"], -2.048) + assert.Nil(t, result.(map[string]interface{})["err"]) + assert.Equal(t, -2.048, result.(map[string]interface{})["val"]) } func TestADS1x15CommandsAnalogRead(t *testing.T) { @@ -91,14 +90,14 @@ func TestADS1x15CommandsAnalogRead(t *testing.T) { // act result := d.Command("AnalogRead")(ads1x15TestPin) // assert - gobottest.Assert(t, result.(map[string]interface{})["err"], nil) - gobottest.Assert(t, result.(map[string]interface{})["val"], -32768) + assert.Nil(t, result.(map[string]interface{})["err"]) + assert.Equal(t, -32768, result.(map[string]interface{})["val"]) } func TestADS1x15_ads1x15BestGainForVoltage(t *testing.T) { g, _ := ads1x15BestGainForVoltage(1.5) - gobottest.Assert(t, g, 2) + assert.Equal(t, 2, g) _, err := ads1x15BestGainForVoltage(20.0) - gobottest.Assert(t, err, errors.New("The maximum voltage which can be read is 6.144000")) + assert.ErrorContains(t, err, "The maximum voltage which can be read is 6.144000") } diff --git a/drivers/i2c/adxl345_driver.go b/drivers/i2c/adxl345_driver.go index 61df38e0b..5084bd2a6 100644 --- a/drivers/i2c/adxl345_driver.go +++ b/drivers/i2c/adxl345_driver.go @@ -15,8 +15,10 @@ const ( adxl345DefaultAddress = 0x53 ) -type ADXL345RateConfig uint8 -type ADXL345FsRangeConfig uint8 +type ( + ADXL345RateConfig uint8 + ADXL345FsRangeConfig uint8 +) const ( // registers are named according to the datasheet diff --git a/drivers/i2c/adxl345_driver_test.go b/drivers/i2c/adxl345_driver_test.go index d2f98f88c..51e4b287e 100644 --- a/drivers/i2c/adxl345_driver_test.go +++ b/drivers/i2c/adxl345_driver_test.go @@ -5,8 +5,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -25,21 +25,21 @@ func TestNewADXL345Driver(t *testing.T) { if !ok { t.Errorf("NewADXL345Driver() should have returned a *ADXL345Driver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "ADXL345"), true) - gobottest.Assert(t, d.defaultAddress, 0x53) - gobottest.Assert(t, d.powerCtl.measure, uint8(1)) - gobottest.Assert(t, d.dataFormat.fullScaleRange, ADXL345FsRangeConfig(0x00)) - gobottest.Assert(t, d.bwRate.rate, ADXL345RateConfig(0x0A)) - gobottest.Assert(t, d.bwRate.lowPower, true) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "ADXL345")) + assert.Equal(t, 0x53, d.defaultAddress) + assert.Equal(t, uint8(1), d.powerCtl.measure) + assert.Equal(t, ADXL345FsRangeConfig(0x00), d.dataFormat.fullScaleRange) + assert.Equal(t, ADXL345RateConfig(0x0A), d.bwRate.rate) + assert.True(t, d.bwRate.lowPower) } func TestADXL345Options(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option and // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". d := NewADXL345Driver(newI2cTestAdaptor(), WithBus(2), WithADXL345LowPowerMode(false)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) - gobottest.Assert(t, d.bwRate.lowPower, false) + assert.Equal(t, 2, d.GetBusOrDefault(1)) + assert.False(t, d.bwRate.lowPower) } func TestADXL345WithADXL345DataOutputRate(t *testing.T) { @@ -52,8 +52,8 @@ func TestADXL345WithADXL345DataOutputRate(t *testing.T) { // act WithADXL345DataOutputRate(setVal)(d) // assert - gobottest.Assert(t, d.bwRate.rate, setVal) - gobottest.Assert(t, len(a.written), 0) + assert.Equal(t, setVal, d.bwRate.rate) + assert.Equal(t, 0, len(a.written)) } func TestADXL345WithADXL345FullScaleRange(t *testing.T) { @@ -66,8 +66,8 @@ func TestADXL345WithADXL345FullScaleRange(t *testing.T) { // act WithADXL345FullScaleRange(setVal)(d) // assert - gobottest.Assert(t, d.dataFormat.fullScaleRange, setVal) - gobottest.Assert(t, len(a.written), 0) + assert.Equal(t, setVal, d.dataFormat.fullScaleRange) + assert.Equal(t, 0, len(a.written)) } func TestADXL345UseLowPower(t *testing.T) { @@ -85,11 +85,11 @@ func TestADXL345UseLowPower(t *testing.T) { // act err := d.UseLowPower(setVal) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, d.bwRate.lowPower, setVal) - gobottest.Assert(t, len(a.written), 2) - gobottest.Assert(t, a.written[0], wantReg) - gobottest.Assert(t, a.written[1], wantVal) + assert.NoError(t, err) + assert.Equal(t, setVal, d.bwRate.lowPower) + assert.Equal(t, 2, len(a.written)) + assert.Equal(t, wantReg, a.written[0]) + assert.Equal(t, wantVal, a.written[1]) } func TestADXL345SetRate(t *testing.T) { @@ -107,11 +107,11 @@ func TestADXL345SetRate(t *testing.T) { // act err := d.SetRate(setVal) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, d.bwRate.rate, setVal) - gobottest.Assert(t, len(a.written), 2) - gobottest.Assert(t, a.written[0], wantReg) - gobottest.Assert(t, a.written[1], wantVal) + assert.NoError(t, err) + assert.Equal(t, setVal, d.bwRate.rate) + assert.Equal(t, 2, len(a.written)) + assert.Equal(t, wantReg, a.written[0]) + assert.Equal(t, wantVal, a.written[1]) } func TestADXL345SetRange(t *testing.T) { @@ -129,11 +129,11 @@ func TestADXL345SetRange(t *testing.T) { // act err := d.SetRange(setVal) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, d.dataFormat.fullScaleRange, setVal) - gobottest.Assert(t, len(a.written), 2) - gobottest.Assert(t, a.written[0], wantReg) - gobottest.Assert(t, a.written[1], wantVal) + assert.NoError(t, err) + assert.Equal(t, setVal, d.dataFormat.fullScaleRange) + assert.Equal(t, 2, len(a.written)) + assert.Equal(t, wantReg, a.written[0]) + assert.Equal(t, wantVal, a.written[1]) } func TestADXL345RawXYZ(t *testing.T) { @@ -143,7 +143,7 @@ func TestADXL345RawXYZ(t *testing.T) { // * apply two's complement converter // // arrange - var tests = map[string]struct { + tests := map[string]struct { inputX []uint8 inputY []uint8 inputZ []uint8 @@ -184,13 +184,13 @@ func TestADXL345RawXYZ(t *testing.T) { // act gotX, gotY, gotZ, err := d.RawXYZ() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, gotX, tc.wantX) - gobottest.Assert(t, gotY, tc.wantY) - gobottest.Assert(t, gotZ, tc.wantZ) - gobottest.Assert(t, numCallsRead, 1) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], uint8(0x32)) + assert.NoError(t, err) + assert.Equal(t, tc.wantX, gotX) + assert.Equal(t, tc.wantY, gotY) + assert.Equal(t, tc.wantZ, gotZ) + assert.Equal(t, 1, numCallsRead) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, uint8(0x32), a.written[0]) }) } } @@ -205,12 +205,12 @@ func TestADXL345RawXYZError(t *testing.T) { // act _, _, _, err := d.RawXYZ() // assert - gobottest.Assert(t, err, errors.New("read error")) + assert.ErrorContains(t, err, "read error") } func TestADXL345XYZ(t *testing.T) { // arrange - var tests = map[string]struct { + tests := map[string]struct { inputX []uint8 inputY []uint8 inputZ []uint8 @@ -252,9 +252,9 @@ func TestADXL345XYZ(t *testing.T) { // act x, y, z, _ := d.XYZ() // assert - gobottest.Assert(t, x, tc.wantX) - gobottest.Assert(t, y, tc.wantY) - gobottest.Assert(t, z, tc.wantZ) + assert.Equal(t, tc.wantX, x) + assert.Equal(t, tc.wantY, y) + assert.Equal(t, tc.wantZ, z) }) } } @@ -269,7 +269,7 @@ func TestADXL345XYZError(t *testing.T) { // act _, _, _, err := d.XYZ() // assert - gobottest.Assert(t, err, errors.New("read error")) + assert.ErrorContains(t, err, "read error") } func TestADXL345_initialize(t *testing.T) { @@ -292,14 +292,14 @@ func TestADXL345_initialize(t *testing.T) { // act, assert - initialize() must be called on Start() err := d.Start() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 6) - gobottest.Assert(t, a.written[0], wantRateReg) - gobottest.Assert(t, a.written[1], wantRateRegVal) - gobottest.Assert(t, a.written[2], wantPwrReg) - gobottest.Assert(t, a.written[3], wantPwrRegVal) - gobottest.Assert(t, a.written[4], wantFormatReg) - gobottest.Assert(t, a.written[5], wantFormatRegVal) + assert.NoError(t, err) + assert.Equal(t, 6, len(a.written)) + assert.Equal(t, wantRateReg, a.written[0]) + assert.Equal(t, wantRateRegVal, a.written[1]) + assert.Equal(t, wantPwrReg, a.written[2]) + assert.Equal(t, wantPwrRegVal, a.written[3]) + assert.Equal(t, wantFormatReg, a.written[4]) + assert.Equal(t, wantFormatRegVal, a.written[5]) } func TestADXL345_shutdown(t *testing.T) { @@ -316,8 +316,8 @@ func TestADXL345_shutdown(t *testing.T) { // act, assert - shutdown() must be called on Halt() err := d.Halt() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 2) - gobottest.Assert(t, a.written[0], wantReg) - gobottest.Assert(t, a.written[1], wantVal) + assert.NoError(t, err) + assert.Equal(t, 2, len(a.written)) + assert.Equal(t, wantReg, a.written[0]) + assert.Equal(t, wantVal, a.written[1]) } diff --git a/drivers/i2c/bh1750_driver.go b/drivers/i2c/bh1750_driver.go index 0eee86c03..a2bbe9c2b 100644 --- a/drivers/i2c/bh1750_driver.go +++ b/drivers/i2c/bh1750_driver.go @@ -20,7 +20,6 @@ const ( ) // BH1750Driver is a driver for the BH1750 digital Ambient Light Sensor IC for I²C bus interface. -// type BH1750Driver struct { *Driver mode byte @@ -28,12 +27,13 @@ type BH1750Driver struct { // NewBH1750Driver creates a new driver with specified i2c interface // Params: -// c Connector - the Adaptor to use with this Driver +// +// c Connector - the Adaptor to use with this Driver // // Optional params: -// i2c.WithBus(int): bus to use with this driver -// i2c.WithAddress(int): address to use with this driver // +// i2c.WithBus(int): bus to use with this driver +// i2c.WithAddress(int): address to use with this driver func NewBH1750Driver(c Connector, options ...func(Config)) *BH1750Driver { h := &BH1750Driver{ Driver: NewDriver(c, "BH1750", bh1750DefaultAddress), @@ -51,7 +51,6 @@ func NewBH1750Driver(c Connector, options ...func(Config)) *BH1750Driver { // RawSensorData returns the raw value from the bh1750 func (h *BH1750Driver) RawSensorData() (level int, err error) { - buf := []byte{0, 0} bytesRead, err := h.connection.Read(buf) if bytesRead != 2 { @@ -68,7 +67,6 @@ func (h *BH1750Driver) RawSensorData() (level int, err error) { // Lux returns the adjusted value from the bh1750 func (h *BH1750Driver) Lux() (lux int, err error) { - lux, err = h.RawSensorData() lux = int(float64(lux) / 1.2) diff --git a/drivers/i2c/bh1750_driver_test.go b/drivers/i2c/bh1750_driver_test.go index 9d8fc94a1..c75f59bd3 100644 --- a/drivers/i2c/bh1750_driver_test.go +++ b/drivers/i2c/bh1750_driver_test.go @@ -1,14 +1,13 @@ package i2c import ( + "bytes" "errors" "strings" "testing" - "bytes" - + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -30,32 +29,32 @@ func TestNewBH1750Driver(t *testing.T) { if !ok { t.Errorf("NewBH1750Driver() should have returned a *BH1750Driver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "BH1750"), true) - gobottest.Assert(t, d.defaultAddress, 0x23) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "BH1750")) + assert.Equal(t, 0x23, d.defaultAddress) } func TestBH1750Options(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option and // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". d := NewBH1750Driver(newI2cTestAdaptor(), WithBus(2)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) + assert.Equal(t, 2, d.GetBusOrDefault(1)) } func TestBH1750Start(t *testing.T) { d := NewBH1750Driver(newI2cTestAdaptor()) - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestBH1750Halt(t *testing.T) { d, _ := initTestBH1750DriverWithStubbedAdaptor() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestBH1750NullLux(t *testing.T) { d, _ := initTestBH1750DriverWithStubbedAdaptor() lux, _ := d.Lux() - gobottest.Assert(t, lux, 0) + assert.Equal(t, 0, lux) } func TestBH1750Lux(t *testing.T) { @@ -68,13 +67,13 @@ func TestBH1750Lux(t *testing.T) { } lux, _ := d.Lux() - gobottest.Assert(t, lux, 1213) + assert.Equal(t, 1213, lux) } func TestBH1750NullRawSensorData(t *testing.T) { d, _ := initTestBH1750DriverWithStubbedAdaptor() level, _ := d.RawSensorData() - gobottest.Assert(t, level, 0) + assert.Equal(t, 0, level) } func TestBH1750RawSensorData(t *testing.T) { @@ -87,7 +86,7 @@ func TestBH1750RawSensorData(t *testing.T) { } level, _ := d.RawSensorData() - gobottest.Assert(t, level, 1456) + assert.Equal(t, 1456, level) } func TestBH1750LuxError(t *testing.T) { @@ -97,7 +96,7 @@ func TestBH1750LuxError(t *testing.T) { } _, err := d.Lux() - gobottest.Assert(t, err, errors.New("wrong number of bytes read")) + assert.ErrorContains(t, err, "wrong number of bytes read") } func TestBH1750RawSensorDataError(t *testing.T) { @@ -107,5 +106,5 @@ func TestBH1750RawSensorDataError(t *testing.T) { } _, err := d.RawSensorData() - gobottest.Assert(t, err, errors.New("wrong number of bytes read")) + assert.ErrorContains(t, err, "wrong number of bytes read") } diff --git a/drivers/i2c/blinkm_driver.go b/drivers/i2c/blinkm_driver.go index 525331343..ef8711639 100644 --- a/drivers/i2c/blinkm_driver.go +++ b/drivers/i2c/blinkm_driver.go @@ -14,12 +14,13 @@ type BlinkMDriver struct { // NewBlinkMDriver creates a new BlinkMDriver. // // Params: -// c Connector - the Adaptor to use with this Driver +// +// c Connector - the Adaptor to use with this Driver // // Optional params: -// i2c.WithBus(int): bus to use with this driver -// i2c.WithAddress(int): address to use with this driver // +// i2c.WithBus(int): bus to use with this driver +// i2c.WithAddress(int): address to use with this driver func NewBlinkMDriver(c Connector, options ...func(Config)) *BlinkMDriver { b := &BlinkMDriver{ Driver: NewDriver(c, "BlinkM", blinkmDefaultAddress), diff --git a/drivers/i2c/blinkm_driver_test.go b/drivers/i2c/blinkm_driver_test.go index 2093b2b3f..3e0811cc3 100644 --- a/drivers/i2c/blinkm_driver_test.go +++ b/drivers/i2c/blinkm_driver_test.go @@ -5,8 +5,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -28,26 +28,26 @@ func TestNewBlinkMDriver(t *testing.T) { if !ok { t.Errorf("NewBlinkMDriver() should have returned a *BlinkMDriver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "BlinkM"), true) - gobottest.Assert(t, d.defaultAddress, 0x09) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "BlinkM")) + assert.Equal(t, 0x09, d.defaultAddress) } func TestBlinkMOptions(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option and // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". d := NewBlinkMDriver(newI2cTestAdaptor(), WithBus(2)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) + assert.Equal(t, 2, d.GetBusOrDefault(1)) } func TestBlinkMStart(t *testing.T) { d := NewBlinkMDriver(newI2cTestAdaptor()) - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestBlinkMHalt(t *testing.T) { d, _ := initTestBlinkMDriverWithStubbedAdaptor() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } // Commands @@ -55,14 +55,14 @@ func TestNewBlinkMDriverCommands_Rgb(t *testing.T) { d, _ := initTestBlinkMDriverWithStubbedAdaptor() result := d.Command("Rgb")(rgb) - gobottest.Assert(t, result, nil) + assert.Nil(t, result) } func TestNewBlinkMDriverCommands_Fade(t *testing.T) { d, _ := initTestBlinkMDriverWithStubbedAdaptor() result := d.Command("Fade")(rgb) - gobottest.Assert(t, result, nil) + assert.Nil(t, result) } func TestNewBlinkMDriverCommands_FirmwareVersion(t *testing.T) { @@ -77,7 +77,7 @@ func TestNewBlinkMDriverCommands_FirmwareVersion(t *testing.T) { result := d.Command("FirmwareVersion")(param) version, _ := d.FirmwareVersion() - gobottest.Assert(t, result.(map[string]interface{})["version"].(string), version) + assert.Equal(t, version, result.(map[string]interface{})["version"].(string)) // When len(data) is not 2 a.i2cReadImpl = func(b []byte) (int, error) { @@ -87,7 +87,7 @@ func TestNewBlinkMDriverCommands_FirmwareVersion(t *testing.T) { result = d.Command("FirmwareVersion")(param) version, _ = d.FirmwareVersion() - gobottest.Assert(t, result.(map[string]interface{})["version"].(string), version) + assert.Equal(t, version, result.(map[string]interface{})["version"].(string)) } func TestNewBlinkMDriverCommands_Color(t *testing.T) { @@ -97,7 +97,7 @@ func TestNewBlinkMDriverCommands_Color(t *testing.T) { result := d.Command("Color")(param) color, _ := d.Color() - gobottest.Assert(t, result.(map[string]interface{})["color"].([]byte), color) + assert.Equal(t, color, result.(map[string]interface{})["color"].([]byte)) } func TestBlinkMFirmwareVersion(t *testing.T) { @@ -109,7 +109,7 @@ func TestBlinkMFirmwareVersion(t *testing.T) { } version, _ := d.FirmwareVersion() - gobottest.Assert(t, version, "99.1") + assert.Equal(t, "99.1", version) // when len(data) is not 2 a.i2cReadImpl = func(b []byte) (int, error) { @@ -118,14 +118,14 @@ func TestBlinkMFirmwareVersion(t *testing.T) { } version, _ = d.FirmwareVersion() - gobottest.Assert(t, version, "") + assert.Equal(t, "", version) a.i2cWriteImpl = func([]byte) (int, error) { return 0, errors.New("write error") } _, err := d.FirmwareVersion() - gobottest.Assert(t, err, errors.New("write error")) + assert.ErrorContains(t, err, "write error") } func TestBlinkMColor(t *testing.T) { @@ -137,7 +137,7 @@ func TestBlinkMColor(t *testing.T) { } color, _ := d.Color() - gobottest.Assert(t, color, []byte{99, 1, 2}) + assert.Equal(t, []byte{99, 1, 2}, color) // when len(data) is not 3 a.i2cReadImpl = func(b []byte) (int, error) { @@ -146,15 +146,14 @@ func TestBlinkMColor(t *testing.T) { } color, _ = d.Color() - gobottest.Assert(t, color, []byte{}) + assert.Equal(t, []byte{}, color) a.i2cWriteImpl = func([]byte) (int, error) { return 0, errors.New("write error") } _, err := d.Color() - gobottest.Assert(t, err, errors.New("write error")) - + assert.ErrorContains(t, err, "write error") } func TestBlinkMFade(t *testing.T) { @@ -164,8 +163,7 @@ func TestBlinkMFade(t *testing.T) { } err := d.Fade(100, 100, 100) - gobottest.Assert(t, err, errors.New("write error")) - + assert.ErrorContains(t, err, "write error") } func TestBlinkMRGB(t *testing.T) { @@ -175,6 +173,5 @@ func TestBlinkMRGB(t *testing.T) { } err := d.Rgb(100, 100, 100) - gobottest.Assert(t, err, errors.New("write error")) - + assert.ErrorContains(t, err, "write error") } diff --git a/drivers/i2c/bme280_driver.go b/drivers/i2c/bme280_driver.go index a42a1851c..d3767cdc1 100644 --- a/drivers/i2c/bme280_driver.go +++ b/drivers/i2c/bme280_driver.go @@ -213,7 +213,6 @@ func (d *BME280Driver) initHumidity() error { } return d.connection.WriteByteData(bmp280RegCtrl, cmr) - } func (d *BME280Driver) rawHumidity() (uint32, error) { diff --git a/drivers/i2c/bme280_driver_test.go b/drivers/i2c/bme280_driver_test.go index 80635ac87..49e049e6c 100644 --- a/drivers/i2c/bme280_driver_test.go +++ b/drivers/i2c/bme280_driver_test.go @@ -6,8 +6,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -25,15 +25,15 @@ func TestNewBME280Driver(t *testing.T) { if !ok { t.Errorf("NewBME280Driver() should have returned a *BME280Driver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "BMP280"), true) - gobottest.Assert(t, d.defaultAddress, 0x77) - gobottest.Assert(t, d.ctrlPwrMode, uint8(0x03)) - gobottest.Assert(t, d.ctrlPressOversamp, BMP280PressureOversampling(0x05)) - gobottest.Assert(t, d.ctrlTempOversamp, BMP280TemperatureOversampling(0x01)) - gobottest.Assert(t, d.ctrlHumOversamp, BME280HumidityOversampling(0x05)) - gobottest.Assert(t, d.confFilter, BMP280IIRFilter(0x00)) - gobottest.Refute(t, d.calCoeffs, nil) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "BMP280")) + assert.Equal(t, 0x77, d.defaultAddress) + assert.Equal(t, uint8(0x03), d.ctrlPwrMode) + assert.Equal(t, BMP280PressureOversampling(0x05), d.ctrlPressOversamp) + assert.Equal(t, BMP280TemperatureOversampling(0x01), d.ctrlTempOversamp) + assert.Equal(t, BME280HumidityOversampling(0x05), d.ctrlHumOversamp) + assert.Equal(t, BMP280IIRFilter(0x00), d.confFilter) + assert.NotNil(t, d.calCoeffs) } func TestBME280Options(t *testing.T) { @@ -44,11 +44,11 @@ func TestBME280Options(t *testing.T) { WithBME280TemperatureOversampling(0x02), WithBME280IIRFilter(0x03), WithBME280HumidityOversampling(0x04)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) - gobottest.Assert(t, d.ctrlPressOversamp, BMP280PressureOversampling(0x01)) - gobottest.Assert(t, d.ctrlTempOversamp, BMP280TemperatureOversampling(0x02)) - gobottest.Assert(t, d.confFilter, BMP280IIRFilter(0x03)) - gobottest.Assert(t, d.ctrlHumOversamp, BME280HumidityOversampling(0x04)) + assert.Equal(t, 2, d.GetBusOrDefault(1)) + assert.Equal(t, BMP280PressureOversampling(0x01), d.ctrlPressOversamp) + assert.Equal(t, BMP280TemperatureOversampling(0x02), d.ctrlTempOversamp) + assert.Equal(t, BMP280IIRFilter(0x03), d.confFilter) + assert.Equal(t, BME280HumidityOversampling(0x04), d.ctrlHumOversamp) } func TestBME280Measurements(t *testing.T) { @@ -72,8 +72,8 @@ func TestBME280Measurements(t *testing.T) { } _ = bme280.Start() hum, err := bme280.Humidity() - gobottest.Assert(t, err, nil) - gobottest.Assert(t, hum, float32(51.20179)) + assert.NoError(t, err) + assert.Equal(t, float32(51.20179), hum) } func TestBME280InitH1Error(t *testing.T) { @@ -92,7 +92,7 @@ func TestBME280InitH1Error(t *testing.T) { return buf.Len(), nil } - gobottest.Assert(t, bme280.Start(), errors.New("h1 read error")) + assert.ErrorContains(t, bme280.Start(), "h1 read error") } func TestBME280InitH2Error(t *testing.T) { @@ -111,7 +111,7 @@ func TestBME280InitH2Error(t *testing.T) { return buf.Len(), nil } - gobottest.Assert(t, bme280.Start(), errors.New("h2 read error")) + assert.ErrorContains(t, bme280.Start(), "h2 read error") } func TestBME280HumidityWriteError(t *testing.T) { @@ -122,8 +122,8 @@ func TestBME280HumidityWriteError(t *testing.T) { return 0, errors.New("write error") } hum, err := bme280.Humidity() - gobottest.Assert(t, err, errors.New("write error")) - gobottest.Assert(t, hum, float32(0.0)) + assert.ErrorContains(t, err, "write error") + assert.Equal(t, float32(0.0), hum) } func TestBME280HumidityReadError(t *testing.T) { @@ -134,8 +134,8 @@ func TestBME280HumidityReadError(t *testing.T) { return 0, errors.New("read error") } hum, err := bme280.Humidity() - gobottest.Assert(t, err, errors.New("read error")) - gobottest.Assert(t, hum, float32(0.0)) + assert.ErrorContains(t, err, "read error") + assert.Equal(t, float32(0.0), hum) } func TestBME280HumidityNotEnabled(t *testing.T) { @@ -159,8 +159,8 @@ func TestBME280HumidityNotEnabled(t *testing.T) { } _ = bme280.Start() hum, err := bme280.Humidity() - gobottest.Assert(t, err, errors.New("Humidity disabled")) - gobottest.Assert(t, hum, float32(0.0)) + assert.ErrorContains(t, err, "Humidity disabled") + assert.Equal(t, float32(0.0), hum) } func TestBME280_initializationBME280(t *testing.T) { @@ -186,5 +186,5 @@ func TestBME280_initializationBME280(t *testing.T) { } return 0, nil } - gobottest.Assert(t, bme280.Start(), nil) + assert.NoError(t, bme280.Start()) } diff --git a/drivers/i2c/bmp180_driver.go b/drivers/i2c/bmp180_driver.go index 2d52a063e..a4cd1c085 100644 --- a/drivers/i2c/bmp180_driver.go +++ b/drivers/i2c/bmp180_driver.go @@ -160,7 +160,6 @@ func (d *BMP180Driver) initialization() error { return err } return binary.Read(buf, binary.BigEndian, &d.calCoeffs.md) - } func (d *BMP180Driver) rawTemp() (int16, error) { diff --git a/drivers/i2c/bmp180_driver_test.go b/drivers/i2c/bmp180_driver_test.go index 87dfcfca6..39033d9df 100644 --- a/drivers/i2c/bmp180_driver_test.go +++ b/drivers/i2c/bmp180_driver_test.go @@ -8,8 +8,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -28,19 +28,19 @@ func TestNewBMP180Driver(t *testing.T) { if !ok { t.Errorf("NewBMP180Driver() should have returned a *BMP180Driver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "BMP180"), true) - gobottest.Assert(t, d.defaultAddress, 0x77) - gobottest.Assert(t, d.oversampling, BMP180OversamplingMode(0x00)) - gobottest.Refute(t, d.calCoeffs, nil) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "BMP180")) + assert.Equal(t, 0x77, d.defaultAddress) + assert.Equal(t, BMP180OversamplingMode(0x00), d.oversampling) + assert.NotNil(t, d.calCoeffs) } func TestBMP180Options(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option and // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". d := NewBMP180Driver(newI2cTestAdaptor(), WithBus(2), WithBMP180OversamplingMode(0x01)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) - gobottest.Assert(t, d.oversampling, BMP180OversamplingMode(0x01)) + assert.Equal(t, 2, d.GetBusOrDefault(1)) + assert.Equal(t, BMP180OversamplingMode(0x01), d.oversampling) } func TestBMP180Measurements(t *testing.T) { @@ -72,11 +72,11 @@ func TestBMP180Measurements(t *testing.T) { } _ = bmp180.Start() temp, err := bmp180.Temperature() - gobottest.Assert(t, err, nil) - gobottest.Assert(t, temp, float32(15.0)) + assert.NoError(t, err) + assert.Equal(t, float32(15.0), temp) pressure, err := bmp180.Pressure() - gobottest.Assert(t, err, nil) - gobottest.Assert(t, pressure, float32(69964)) + assert.NoError(t, err) + assert.Equal(t, float32(69964), pressure) } func TestBMP180TemperatureError(t *testing.T) { @@ -108,7 +108,7 @@ func TestBMP180TemperatureError(t *testing.T) { } _ = bmp180.Start() _, err := bmp180.Temperature() - gobottest.Assert(t, err, errors.New("temp error")) + assert.ErrorContains(t, err, "temp error") } func TestBMP180PressureError(t *testing.T) { @@ -138,7 +138,7 @@ func TestBMP180PressureError(t *testing.T) { } _ = bmp180.Start() _, err := bmp180.Pressure() - gobottest.Assert(t, err, errors.New("press error")) + assert.ErrorContains(t, err, "press error") } func TestBMP180PressureWriteError(t *testing.T) { @@ -150,7 +150,7 @@ func TestBMP180PressureWriteError(t *testing.T) { } _, err := bmp180.Pressure() - gobottest.Assert(t, err, errors.New("write error")) + assert.ErrorContains(t, err, "write error") } func TestBMP180_initialization(t *testing.T) { @@ -183,26 +183,26 @@ func TestBMP180_initialization(t *testing.T) { // act, assert - initialization() must be called on Start() err := d.Start() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, numCallsRead, 1) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], uint8(0xAA)) - gobottest.Assert(t, d.calCoeffs.ac1, int16(408)) - gobottest.Assert(t, d.calCoeffs.ac2, int16(-72)) - gobottest.Assert(t, d.calCoeffs.ac3, int16(-14383)) - gobottest.Assert(t, d.calCoeffs.ac4, uint16(32741)) - gobottest.Assert(t, d.calCoeffs.ac5, uint16(32757)) - gobottest.Assert(t, d.calCoeffs.ac6, uint16(23153)) - gobottest.Assert(t, d.calCoeffs.b1, int16(6190)) - gobottest.Assert(t, d.calCoeffs.b2, int16(4)) - gobottest.Assert(t, d.calCoeffs.mb, int16(-32768)) - gobottest.Assert(t, d.calCoeffs.mc, int16(-8711)) - gobottest.Assert(t, d.calCoeffs.md, int16(2868)) + assert.NoError(t, err) + assert.Equal(t, 1, numCallsRead) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, uint8(0xAA), a.written[0]) + assert.Equal(t, int16(408), d.calCoeffs.ac1) + assert.Equal(t, int16(-72), d.calCoeffs.ac2) + assert.Equal(t, int16(-14383), d.calCoeffs.ac3) + assert.Equal(t, uint16(32741), d.calCoeffs.ac4) + assert.Equal(t, uint16(32757), d.calCoeffs.ac5) + assert.Equal(t, uint16(23153), d.calCoeffs.ac6) + assert.Equal(t, int16(6190), d.calCoeffs.b1) + assert.Equal(t, int16(4), d.calCoeffs.b2) + assert.Equal(t, int16(-32768), d.calCoeffs.mb) + assert.Equal(t, int16(-8711), d.calCoeffs.mc) + assert.Equal(t, int16(2868), d.calCoeffs.md) } func TestBMP180_bmp180PauseForReading(t *testing.T) { - gobottest.Assert(t, bmp180PauseForReading(BMP180UltraLowPower), time.Duration(5*time.Millisecond)) - gobottest.Assert(t, bmp180PauseForReading(BMP180Standard), time.Duration(8*time.Millisecond)) - gobottest.Assert(t, bmp180PauseForReading(BMP180HighResolution), time.Duration(14*time.Millisecond)) - gobottest.Assert(t, bmp180PauseForReading(BMP180UltraHighResolution), time.Duration(26*time.Millisecond)) + assert.Equal(t, 5*time.Millisecond, bmp180PauseForReading(BMP180UltraLowPower)) + assert.Equal(t, 8*time.Millisecond, bmp180PauseForReading(BMP180Standard)) + assert.Equal(t, 14*time.Millisecond, bmp180PauseForReading(BMP180HighResolution)) + assert.Equal(t, 26*time.Millisecond, bmp180PauseForReading(BMP180UltraHighResolution)) } diff --git a/drivers/i2c/bmp280_driver.go b/drivers/i2c/bmp280_driver.go index cea919de4..ebf5207d0 100644 --- a/drivers/i2c/bmp280_driver.go +++ b/drivers/i2c/bmp280_driver.go @@ -13,9 +13,11 @@ const bmp280Debug = true // this is also true for bme280 (which using this address as well) const bmp280DefaultAddress = 0x77 -type BMP280PressureOversampling uint8 -type BMP280TemperatureOversampling uint8 -type BMP280IIRFilter uint8 +type ( + BMP280PressureOversampling uint8 + BMP280TemperatureOversampling uint8 + BMP280IIRFilter uint8 +) const ( bmp280RegCalib00 = 0x88 // 12 x 16 bit calibration data (T1..T3, P1..P9) @@ -245,7 +247,7 @@ func (d *BMP280Driver) initialization() error { return err } - ctrlReg := uint8(d.ctrlPwrMode) | uint8(d.ctrlPressOversamp)<<2 | uint8(d.ctrlTempOversamp)<<5 + ctrlReg := d.ctrlPwrMode | uint8(d.ctrlPressOversamp)<<2 | uint8(d.ctrlTempOversamp)<<5 if err := d.connection.WriteByteData(bmp280RegCtrl, ctrlReg); err != nil { return err } diff --git a/drivers/i2c/bmp280_driver_test.go b/drivers/i2c/bmp280_driver_test.go index bbbe13c8c..354e8bae1 100644 --- a/drivers/i2c/bmp280_driver_test.go +++ b/drivers/i2c/bmp280_driver_test.go @@ -6,8 +6,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -25,22 +25,22 @@ func TestNewBMP280Driver(t *testing.T) { if !ok { t.Errorf("NewBMP280Driver() should have returned a *BMP280Driver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "BMP280"), true) - gobottest.Assert(t, d.defaultAddress, 0x77) - gobottest.Assert(t, d.ctrlPwrMode, uint8(0x03)) - gobottest.Assert(t, d.ctrlPressOversamp, BMP280PressureOversampling(0x05)) - gobottest.Assert(t, d.ctrlTempOversamp, BMP280TemperatureOversampling(0x01)) - gobottest.Assert(t, d.confFilter, BMP280IIRFilter(0x00)) - gobottest.Refute(t, d.calCoeffs, nil) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "BMP280")) + assert.Equal(t, 0x77, d.defaultAddress) + assert.Equal(t, uint8(0x03), d.ctrlPwrMode) + assert.Equal(t, BMP280PressureOversampling(0x05), d.ctrlPressOversamp) + assert.Equal(t, BMP280TemperatureOversampling(0x01), d.ctrlTempOversamp) + assert.Equal(t, BMP280IIRFilter(0x00), d.confFilter) + assert.NotNil(t, d.calCoeffs) } func TestBMP280Options(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option and // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". d := NewBMP280Driver(newI2cTestAdaptor(), WithBus(2), WithBMP280PressureOversampling(0x04)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) - gobottest.Assert(t, d.ctrlPressOversamp, BMP280PressureOversampling(0x04)) + assert.Equal(t, 2, d.GetBusOrDefault(1)) + assert.Equal(t, BMP280PressureOversampling(0x04), d.ctrlPressOversamp) } func TestWithBMP280TemperatureOversampling(t *testing.T) { @@ -53,8 +53,8 @@ func TestWithBMP280TemperatureOversampling(t *testing.T) { // act WithBMP280TemperatureOversampling(setVal)(d) // assert - gobottest.Assert(t, d.ctrlTempOversamp, setVal) - gobottest.Assert(t, len(a.written), 0) + assert.Equal(t, setVal, d.ctrlTempOversamp) + assert.Equal(t, 0, len(a.written)) } func TestWithBMP280IIRFilter(t *testing.T) { @@ -67,8 +67,8 @@ func TestWithBMP280IIRFilter(t *testing.T) { // act WithBMP280IIRFilter(setVal)(d) // assert - gobottest.Assert(t, d.confFilter, setVal) - gobottest.Assert(t, len(a.written), 0) + assert.Equal(t, setVal, d.confFilter) + assert.Equal(t, 0, len(a.written)) } func TestBMP280Measurements(t *testing.T) { @@ -88,14 +88,14 @@ func TestBMP280Measurements(t *testing.T) { } _ = d.Start() temp, err := d.Temperature() - gobottest.Assert(t, err, nil) - gobottest.Assert(t, temp, float32(25.014637)) + assert.NoError(t, err) + assert.Equal(t, float32(25.014637), temp) pressure, err := d.Pressure() - gobottest.Assert(t, err, nil) - gobottest.Assert(t, pressure, float32(99545.414)) + assert.NoError(t, err) + assert.Equal(t, float32(99545.414), pressure) alt, err := d.Altitude() - gobottest.Assert(t, err, nil) - gobottest.Assert(t, alt, float32(149.22713)) + assert.NoError(t, err) + assert.Equal(t, float32(149.22713), alt) } func TestBMP280TemperatureWriteError(t *testing.T) { @@ -106,8 +106,8 @@ func TestBMP280TemperatureWriteError(t *testing.T) { return 0, errors.New("write error") } temp, err := d.Temperature() - gobottest.Assert(t, err, errors.New("write error")) - gobottest.Assert(t, temp, float32(0.0)) + assert.ErrorContains(t, err, "write error") + assert.Equal(t, float32(0.0), temp) } func TestBMP280TemperatureReadError(t *testing.T) { @@ -118,8 +118,8 @@ func TestBMP280TemperatureReadError(t *testing.T) { return 0, errors.New("read error") } temp, err := d.Temperature() - gobottest.Assert(t, err, errors.New("read error")) - gobottest.Assert(t, temp, float32(0.0)) + assert.ErrorContains(t, err, "read error") + assert.Equal(t, float32(0.0), temp) } func TestBMP280PressureWriteError(t *testing.T) { @@ -130,8 +130,8 @@ func TestBMP280PressureWriteError(t *testing.T) { return 0, errors.New("write error") } press, err := d.Pressure() - gobottest.Assert(t, err, errors.New("write error")) - gobottest.Assert(t, press, float32(0.0)) + assert.ErrorContains(t, err, "write error") + assert.Equal(t, float32(0.0), press) } func TestBMP280PressureReadError(t *testing.T) { @@ -142,8 +142,8 @@ func TestBMP280PressureReadError(t *testing.T) { return 0, errors.New("read error") } press, err := d.Pressure() - gobottest.Assert(t, err, errors.New("read error")) - gobottest.Assert(t, press, float32(0.0)) + assert.ErrorContains(t, err, "read error") + assert.Equal(t, float32(0.0), press) } func TestBMP280_initialization(t *testing.T) { @@ -188,24 +188,24 @@ func TestBMP280_initialization(t *testing.T) { // act, assert - initialization() must be called on Start() err := d.Start() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, numCallsRead, 1) - gobottest.Assert(t, len(a.written), 5) - gobottest.Assert(t, a.written[0], wantCalibReg) - gobottest.Assert(t, a.written[1], wantCtrlReg) - gobottest.Assert(t, a.written[2], wantCtrlRegVal) - gobottest.Assert(t, a.written[3], wantConfReg) - gobottest.Assert(t, a.written[4], wantConfRegVal) - gobottest.Assert(t, d.calCoeffs.t1, uint16(27504)) - gobottest.Assert(t, d.calCoeffs.t2, int16(26435)) - gobottest.Assert(t, d.calCoeffs.t3, int16(-1000)) - gobottest.Assert(t, d.calCoeffs.p1, uint16(36477)) - gobottest.Assert(t, d.calCoeffs.p2, int16(-10685)) - gobottest.Assert(t, d.calCoeffs.p3, int16(3024)) - gobottest.Assert(t, d.calCoeffs.p4, int16(2855)) - gobottest.Assert(t, d.calCoeffs.p5, int16(140)) - gobottest.Assert(t, d.calCoeffs.p6, int16(-7)) - gobottest.Assert(t, d.calCoeffs.p7, int16(15500)) - gobottest.Assert(t, d.calCoeffs.p8, int16(-14600)) - gobottest.Assert(t, d.calCoeffs.p9, int16(6000)) + assert.NoError(t, err) + assert.Equal(t, 1, numCallsRead) + assert.Equal(t, 5, len(a.written)) + assert.Equal(t, wantCalibReg, a.written[0]) + assert.Equal(t, wantCtrlReg, a.written[1]) + assert.Equal(t, wantCtrlRegVal, a.written[2]) + assert.Equal(t, wantConfReg, a.written[3]) + assert.Equal(t, wantConfRegVal, a.written[4]) + assert.Equal(t, uint16(27504), d.calCoeffs.t1) + assert.Equal(t, int16(26435), d.calCoeffs.t2) + assert.Equal(t, int16(-1000), d.calCoeffs.t3) + assert.Equal(t, uint16(36477), d.calCoeffs.p1) + assert.Equal(t, int16(-10685), d.calCoeffs.p2) + assert.Equal(t, int16(3024), d.calCoeffs.p3) + assert.Equal(t, int16(2855), d.calCoeffs.p4) + assert.Equal(t, int16(140), d.calCoeffs.p5) + assert.Equal(t, int16(-7), d.calCoeffs.p6) + assert.Equal(t, int16(15500), d.calCoeffs.p7) + assert.Equal(t, int16(-14600), d.calCoeffs.p8) + assert.Equal(t, int16(6000), d.calCoeffs.p9) } diff --git a/drivers/i2c/bmp388_driver.go b/drivers/i2c/bmp388_driver.go index d7bf2f30b..a5dda145a 100644 --- a/drivers/i2c/bmp388_driver.go +++ b/drivers/i2c/bmp388_driver.go @@ -14,8 +14,10 @@ const bmp388Debug = false const bmp388DefaultAddress = 0x77 // BMP388Accuracy accuracy type -type BMP388Accuracy uint8 -type BMP388IIRFilter uint8 +type ( + BMP388Accuracy uint8 + BMP388IIRFilter uint8 +) const ( bmp388ChipID = 0x50 @@ -136,7 +138,7 @@ func (d *BMP388Driver) Temperature(accuracy BMP388Accuracy) (temp float32, err e var rawT int32 - mode := uint8(d.ctrlPwrMode)<<4 | bmp388PWRCTRLPressEnableBit | bmp388PWRCTRLTempEnableBit + mode := d.ctrlPwrMode<<4 | bmp388PWRCTRLPressEnableBit | bmp388PWRCTRLTempEnableBit if err = d.connection.WriteByteData(bmp388RegPWRCTRL, mode); err != nil { return 0, err } @@ -160,7 +162,7 @@ func (d *BMP388Driver) Pressure(accuracy BMP388Accuracy) (press float32, err err var rawT, rawP int32 - mode := uint8(d.ctrlPwrMode)<<4 | bmp388PWRCTRLPressEnableBit | bmp388PWRCTRLTempEnableBit + mode := d.ctrlPwrMode<<4 | bmp388PWRCTRLPressEnableBit | bmp388PWRCTRLTempEnableBit if err = d.connection.WriteByteData(bmp388RegPWRCTRL, mode); err != nil { return 0, err } @@ -194,7 +196,6 @@ func (d *BMP388Driver) Altitude(accuracy BMP388Accuracy) (alt float32, err error // initialization reads the calibration coefficients. func (d *BMP388Driver) initialization() error { - chipID, err := d.connection.ReadByteData(bmp388RegChipID) if err != nil { return err diff --git a/drivers/i2c/bmp388_driver_test.go b/drivers/i2c/bmp388_driver_test.go index fb0ce1b59..59d3f224b 100644 --- a/drivers/i2c/bmp388_driver_test.go +++ b/drivers/i2c/bmp388_driver_test.go @@ -7,8 +7,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -44,20 +44,20 @@ func TestNewBMP388Driver(t *testing.T) { if !ok { t.Errorf("NewBMP388Driver() should have returned a *BMP388Driver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "BMP388"), true) - gobottest.Assert(t, d.defaultAddress, 0x77) - gobottest.Assert(t, d.ctrlPwrMode, uint8(0x01)) // forced mode - gobottest.Assert(t, d.confFilter, BMP388IIRFilter(0x00)) // filter off - gobottest.Refute(t, d.calCoeffs, nil) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "BMP388")) + assert.Equal(t, 0x77, d.defaultAddress) + assert.Equal(t, uint8(0x01), d.ctrlPwrMode) // forced mode + assert.Equal(t, BMP388IIRFilter(0x00), d.confFilter) // filter off + assert.NotNil(t, d.calCoeffs) } func TestBMP388Options(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option and // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". d := NewBMP388Driver(newI2cTestAdaptor(), WithBus(2), WithBMP388IIRFilter(BMP388IIRFilter(0x03))) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) - gobottest.Assert(t, d.confFilter, BMP388IIRFilter(0x03)) + assert.Equal(t, 2, d.GetBusOrDefault(1)) + assert.Equal(t, BMP388IIRFilter(0x03), d.confFilter) } func TestBMP388Measurements(t *testing.T) { @@ -84,14 +84,14 @@ func TestBMP388Measurements(t *testing.T) { } _ = d.Start() temp, err := d.Temperature(2) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, temp, float32(22.906143)) + assert.NoError(t, err) + assert.Equal(t, float32(22.906143), temp) pressure, err := d.Pressure(2) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, pressure, float32(98874.85)) + assert.NoError(t, err) + assert.Equal(t, float32(98874.85), pressure) alt, err := d.Altitude(2) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, alt, float32(205.89395)) + assert.NoError(t, err) + assert.Equal(t, float32(205.89395), alt) } func TestBMP388TemperatureWriteError(t *testing.T) { @@ -102,8 +102,8 @@ func TestBMP388TemperatureWriteError(t *testing.T) { return 0, errors.New("write error") } temp, err := d.Temperature(2) - gobottest.Assert(t, err, errors.New("write error")) - gobottest.Assert(t, temp, float32(0.0)) + assert.ErrorContains(t, err, "write error") + assert.Equal(t, float32(0.0), temp) } func TestBMP388TemperatureReadError(t *testing.T) { @@ -114,8 +114,8 @@ func TestBMP388TemperatureReadError(t *testing.T) { return 0, errors.New("read error") } temp, err := d.Temperature(2) - gobottest.Assert(t, err, errors.New("read error")) - gobottest.Assert(t, temp, float32(0.0)) + assert.ErrorContains(t, err, "read error") + assert.Equal(t, float32(0.0), temp) } func TestBMP388PressureWriteError(t *testing.T) { @@ -126,8 +126,8 @@ func TestBMP388PressureWriteError(t *testing.T) { return 0, errors.New("write error") } press, err := d.Pressure(2) - gobottest.Assert(t, err, errors.New("write error")) - gobottest.Assert(t, press, float32(0.0)) + assert.ErrorContains(t, err, "write error") + assert.Equal(t, float32(0.0), press) } func TestBMP388PressureReadError(t *testing.T) { @@ -138,8 +138,8 @@ func TestBMP388PressureReadError(t *testing.T) { return 0, errors.New("read error") } press, err := d.Pressure(2) - gobottest.Assert(t, err, errors.New("read error")) - gobottest.Assert(t, press, float32(0.0)) + assert.ErrorContains(t, err, "read error") + assert.Equal(t, float32(0.0), press) } func TestBMP388_initialization(t *testing.T) { @@ -176,25 +176,25 @@ func TestBMP388_initialization(t *testing.T) { // act, assert - initialization() must be called on Start() err := d.Start() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, numCallsRead, 2) - gobottest.Assert(t, len(a.written), 6) - gobottest.Assert(t, a.written[0], wantChipIDReg) - gobottest.Assert(t, a.written[1], wantCalibReg) - gobottest.Assert(t, a.written[2], wantCommandReg) - gobottest.Assert(t, a.written[3], wantCommandRegVal) - gobottest.Assert(t, a.written[4], wantConfReg) - gobottest.Assert(t, a.written[5], wantConfRegVal) - gobottest.Assert(t, d.calCoeffs.t1, float32(7.021568e+06)) - gobottest.Assert(t, d.calCoeffs.t2, float32(1.7549843e-05)) - gobottest.Assert(t, d.calCoeffs.t3, float32(-3.5527137e-14)) - gobottest.Assert(t, d.calCoeffs.p1, float32(-0.015769958)) - gobottest.Assert(t, d.calCoeffs.p2, float32(-3.5410747e-05)) - gobottest.Assert(t, d.calCoeffs.p3, float32(8.1490725e-09)) - gobottest.Assert(t, d.calCoeffs.p4, float32(0)) - gobottest.Assert(t, d.calCoeffs.p5, float32(208056)) - gobottest.Assert(t, d.calCoeffs.p6, float32(490.875)) - gobottest.Assert(t, d.calCoeffs.p7, float32(-0.05078125)) - gobottest.Assert(t, d.calCoeffs.p8, float32(-0.00030517578)) - gobottest.Assert(t, d.calCoeffs.p9, float32(5.8957283e-11)) + assert.NoError(t, err) + assert.Equal(t, 2, numCallsRead) + assert.Equal(t, 6, len(a.written)) + assert.Equal(t, wantChipIDReg, a.written[0]) + assert.Equal(t, wantCalibReg, a.written[1]) + assert.Equal(t, wantCommandReg, a.written[2]) + assert.Equal(t, wantCommandRegVal, a.written[3]) + assert.Equal(t, wantConfReg, a.written[4]) + assert.Equal(t, wantConfRegVal, a.written[5]) + assert.Equal(t, float32(7.021568e+06), d.calCoeffs.t1) + assert.Equal(t, float32(1.7549843e-05), d.calCoeffs.t2) + assert.Equal(t, float32(-3.5527137e-14), d.calCoeffs.t3) + assert.Equal(t, float32(-0.015769958), d.calCoeffs.p1) + assert.Equal(t, float32(-3.5410747e-05), d.calCoeffs.p2) + assert.Equal(t, float32(8.1490725e-09), d.calCoeffs.p3) + assert.Equal(t, float32(0), d.calCoeffs.p4) + assert.Equal(t, float32(208056), d.calCoeffs.p5) + assert.Equal(t, float32(490.875), d.calCoeffs.p6) + assert.Equal(t, float32(-0.05078125), d.calCoeffs.p7) + assert.Equal(t, float32(-0.00030517578), d.calCoeffs.p8) + assert.Equal(t, float32(5.8957283e-11), d.calCoeffs.p9) } diff --git a/drivers/i2c/ccs811_driver.go b/drivers/i2c/ccs811_driver.go index 1d50e6b4f..8434d770d 100644 --- a/drivers/i2c/ccs811_driver.go +++ b/drivers/i2c/ccs811_driver.go @@ -20,33 +20,33 @@ const ( const ( - //the default I2C address for the ccs811 applies for ADDR to GND, for ADDR to VDD it will be 0x5B + // the default I2C address for the ccs811 applies for ADDR to GND, for ADDR to VDD it will be 0x5B ccs811DefaultAddress = 0x5A - //Registers, all definitions have been taken from the datasheet - //Single byte read only register which indicates if a device is active, if new data is available or if an error occurred. + // Registers, all definitions have been taken from the datasheet + // Single byte read only register which indicates if a device is active, if new data is available or if an error occurred. ccs811RegStatus = 0x00 - //This is Single byte register, which is used to enable sensor drive mode and interrupts. + // This is Single byte register, which is used to enable sensor drive mode and interrupts. ccs811RegMeasMode = 0x01 - //This multi-byte read only register contains the calculated eCO2 (ppm) and eTVOC (ppb) values followed by the STATUS register, ERROR_ID register and the RAW_DATA register. + // This multi-byte read only register contains the calculated eCO2 (ppm) and eTVOC (ppb) values followed by the STATUS register, ERROR_ID register and the RAW_DATA register. ccs811RegAlgResultData = 0x02 - //Two byte read only register which contains the latest readings from the sensor. - //ccs811RegRawData = 0x03 - //A multi-byte register that can be written with the current Humidity and Temperature values if known. - //ccs811RegEnvData = 0x05 - //Register that holds the NTC value used for temperature calcualtions + // Two byte read only register which contains the latest readings from the sensor. + // ccs811RegRawData = 0x03 + // A multi-byte register that can be written with the current Humidity and Temperature values if known. + // ccs811RegEnvData = 0x05 + // Register that holds the NTC value used for temperature calculations ccs811RegNtc = 0x06 - //Asserting the SW_RESET will restart the CCS811 in Boot mode to enable new application firmware to be downloaded. + // Asserting the SW_RESET will restart the CCS811 in Boot mode to enable new application firmware to be downloaded. ccs811RegSwReset = 0xFF - //Single byte read only register which holds the HW ID which is 0x81 for this family of CCS81x devices. + // Single byte read only register which holds the HW ID which is 0x81 for this family of CCS81x devices. ccs811RegHwID = 0x20 - //Single byte read only register that contains the hardware version. The value is 0x1X + // Single byte read only register that contains the hardware version. The value is 0x1X ccs811RegHwVersion = 0x21 - //Two byte read only register which contain the version of the firmware bootloader stored in the CCS811 in the format Major.Minor.Trivial + // Two byte read only register which contain the version of the firmware bootloader stored in the CCS811 in the format Major.Minor.Trivial ccs811RegFwBootVersion = 0x23 - //Two byte read only register which contain the version of the firmware application stored in the CCS811 in the format Major.Minor.Trivial + // Two byte read only register which contain the version of the firmware application stored in the CCS811 in the format Major.Minor.Trivial ccs811RegFwAppVersion = 0x24 - //To change the mode of the CCS811 from Boot mode to running the application, a single byte write of 0xF4 is required. + // To change the mode of the CCS811 from Boot mode to running the application, a single byte write of 0xF4 is required. ccs811RegAppStart = 0xF4 // Constants @@ -54,21 +54,19 @@ const ( ccs811HwIDCode = 0x81 ) -var ( - // The sequence of bytes needed to do a software reset - ccs811SwResetSequence = []byte{0x11, 0xE5, 0x72, 0x8A} -) +// The sequence of bytes needed to do a software reset +var ccs811SwResetSequence = []byte{0x11, 0xE5, 0x72, 0x8A} // CCS811Status represents the current status of the device defined by the ccs811RegStatus. // The following definitions were taken from https://ams.com/documents/20143/36005/CCS811_DS000459_6-00.pdf/c7091525-c7e5-37ac-eedb-b6c6828b0dcf#page=15 type CCS811Status struct { - //There is some sort of error on the i2c bus or there is an error with the internal sensor + // There is some sort of error on the i2c bus or there is an error with the internal sensor HasError byte - //A new data sample is ready in ccs811RegAlgResultData + // A new data sample is ready in ccs811RegAlgResultData DataReady byte - //Valid application firmware loaded + // Valid application firmware loaded AppValid byte - //Firmware is in application mode. CCS811 is ready to take sensor measurements + // Firmware is in application mode. CCS811 is ready to take sensor measurements FwMode byte } @@ -86,12 +84,12 @@ func NewCCS811Status(data uint8) *CCS811Status { // The following definitions were taken from the bit fields of the ccs811RegMeasMode defined in // https://ams.com/documents/20143/36005/CCS811_DS000459_6-00.pdf/c7091525-c7e5-37ac-eedb-b6c6828b0dcf#page=16 type CCS811MeasMode struct { - //If intThresh is 1 a data measurement will only be taken when the sensor value meets the threshold constraint. - //The threshold value is set in the threshold register (0x10) + // If intThresh is 1 a data measurement will only be taken when the sensor value meets the threshold constraint. + // The threshold value is set in the threshold register (0x10) intThresh uint8 - //If intDataRdy is 1, the nINT signal (pin 3 of the device) will be driven low when new data is available. + // If intDataRdy is 1, the nINT signal (pin 3 of the device) will be driven low when new data is available. intDataRdy uint8 - //driveMode represents the sampling rate of the sensor. If the value is 0, the measurement process is idle. + // driveMode represents the sampling rate of the sensor. If the value is 0, the measurement process is idle. driveMode CCS811DriveMode } @@ -123,7 +121,7 @@ func NewCCS811Driver(c Connector, options ...func(Config)) *CCS811Driver { d := &CCS811Driver{ Driver: NewDriver(c, "CCS811", ccs811DefaultAddress), measMode: NewCCS811MeasMode(), - //Recommended resistance value is 100,000 + // Recommended resistance value is 100,000 ntcResistanceValue: 100000, } d.afterStart = d.initialize @@ -205,7 +203,7 @@ func (d *CCS811Driver) GetStatus() (*CCS811Status, error) { return cs, nil } -// GetTemperature returns the device temperature in celcius. +// GetTemperature returns the device temperature in celsius. // If you do not have an NTC resistor installed, this function should not be called func (d *CCS811Driver) GetTemperature() (float32, error) { d.mutex.Lock() @@ -319,7 +317,7 @@ func (d *CCS811Driver) resetDevice() error { // startApp starts the app code in the device. This operation has to be done after a // software reset to start taking sensor measurements. func (d *CCS811Driver) startApp() error { - //Write without data is needed to start the app code + // Write without data is needed to start the app code _, err := d.connection.Write([]byte{ccs811RegAppStart}) return err } diff --git a/drivers/i2c/ccs811_driver_test.go b/drivers/i2c/ccs811_driver_test.go index 56f01cfe6..b28a554d5 100644 --- a/drivers/i2c/ccs811_driver_test.go +++ b/drivers/i2c/ccs811_driver_test.go @@ -5,8 +5,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -24,29 +24,29 @@ func TestNewCCS811Driver(t *testing.T) { if !ok { t.Errorf("NewCCS811Driver() should have returned a *CCS811Driver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "CCS811"), true) - gobottest.Assert(t, d.defaultAddress, 0x5A) - gobottest.Refute(t, d.measMode, nil) - gobottest.Assert(t, d.ntcResistanceValue, uint32(100000)) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "CCS811")) + assert.Equal(t, 0x5A, d.defaultAddress) + assert.NotNil(t, d.measMode) + assert.Equal(t, uint32(100000), d.ntcResistanceValue) } func TestCCS811Options(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option and // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". d := NewCCS811Driver(newI2cTestAdaptor(), WithBus(2), WithAddress(0xFF), WithCCS811NTCResistance(0xFF)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) - gobottest.Assert(t, d.GetAddressOrDefault(0x5a), 0xFF) - gobottest.Assert(t, d.ntcResistanceValue, uint32(0xFF)) + assert.Equal(t, 2, d.GetBusOrDefault(1)) + assert.Equal(t, 0xFF, d.GetAddressOrDefault(0x5a)) + assert.Equal(t, uint32(0xFF), d.ntcResistanceValue) } func TestCCS811WithCCS811MeasMode(t *testing.T) { d := NewCCS811Driver(newI2cTestAdaptor(), WithCCS811MeasMode(CCS811DriveMode10Sec)) - gobottest.Assert(t, d.measMode.driveMode, CCS811DriveMode(CCS811DriveMode10Sec)) + assert.Equal(t, CCS811DriveMode10Sec, d.measMode.driveMode) } func TestCCS811GetGasData(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { readReturn func([]byte) (int, error) eco2 uint16 tvoc uint16 @@ -91,15 +91,15 @@ func TestCCS811GetGasData(t *testing.T) { // act eco2, tvoc, err := d.GetGasData() // assert - gobottest.Assert(t, eco2, tc.eco2) - gobottest.Assert(t, tvoc, tc.tvoc) - gobottest.Assert(t, err, tc.err) + assert.Equal(t, tc.eco2, eco2) + assert.Equal(t, tc.tvoc, tvoc) + assert.Equal(t, tc.err, err) }) } } func TestCCS811GetTemperature(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { readReturn func([]byte) (int, error) temp float32 err error @@ -148,14 +148,14 @@ func TestCCS811GetTemperature(t *testing.T) { // act temp, err := d.GetTemperature() // assert - gobottest.Assert(t, temp, tc.temp) - gobottest.Assert(t, err, tc.err) + assert.Equal(t, tc.temp, temp) + assert.Equal(t, tc.err, err) }) } } func TestCCS811HasData(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { readReturn func([]byte) (int, error) result bool err error @@ -212,8 +212,8 @@ func TestCCS811HasData(t *testing.T) { // act result, err := d.HasData() // assert - gobottest.Assert(t, result, tc.result) - gobottest.Assert(t, err, tc.err) + assert.Equal(t, tc.result, result) + assert.Equal(t, tc.err, err) }) } } @@ -255,13 +255,13 @@ func TestCCS811_initialize(t *testing.T) { // arrange, act - initialize() must be called on Start() err := d.Start() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, numCallsRead, 1) - gobottest.Assert(t, len(a.written), 9) - gobottest.Assert(t, a.written[0], wantChipIDReg) - gobottest.Assert(t, a.written[1], wantResetReg) - gobottest.Assert(t, a.written[2:6], wantResetRegSequence) - gobottest.Assert(t, a.written[6], wantAppStartReg) - gobottest.Assert(t, a.written[7], wantMeasReg) - gobottest.Assert(t, a.written[8], wantMeasRegVal) + assert.NoError(t, err) + assert.Equal(t, 1, numCallsRead) + assert.Equal(t, 9, len(a.written)) + assert.Equal(t, wantChipIDReg, a.written[0]) + assert.Equal(t, wantResetReg, a.written[1]) + assert.Equal(t, wantResetRegSequence, a.written[2:6]) + assert.Equal(t, wantAppStartReg, a.written[6]) + assert.Equal(t, wantMeasReg, a.written[7]) + assert.Equal(t, wantMeasRegVal, a.written[8]) } diff --git a/drivers/i2c/drv2605l_driver.go b/drivers/i2c/drv2605l_driver.go index 24877a5ad..5adbbaf17 100644 --- a/drivers/i2c/drv2605l_driver.go +++ b/drivers/i2c/drv2605l_driver.go @@ -65,10 +65,9 @@ const ( // // Basic use: // -// haptic := i2c.NewDRV2605Driver(adaptor) -// haptic.SetSequence([]byte{1, 13}) -// haptic.Go() -// +// haptic := i2c.NewDRV2605Driver(adaptor) +// haptic.SetSequence([]byte{1, 13}) +// haptic.Go() type DRV2605LDriver struct { *Driver } @@ -76,12 +75,13 @@ type DRV2605LDriver struct { // NewDRV2605LDriver creates a new driver for the DRV2605L device. // // Params: -// c Connector - the Adaptor to use with this Driver +// +// c Connector - the Adaptor to use with this Driver // // Optional params: -// i2c.WithBus(int): bus to use with this driver -// i2c.WithAddress(int): address to use with this driver // +// i2c.WithBus(int): bus to use with this driver +// i2c.WithAddress(int): address to use with this driver func NewDRV2605LDriver(c Connector, options ...func(Config)) *DRV2605LDriver { d := &DRV2605LDriver{ Driver: NewDriver(c, "DRV2605L", drv2605DefaultAddress), diff --git a/drivers/i2c/drv2605l_driver_test.go b/drivers/i2c/drv2605l_driver_test.go index 7fd988847..6ec3bda11 100644 --- a/drivers/i2c/drv2605l_driver_test.go +++ b/drivers/i2c/drv2605l_driver_test.go @@ -7,8 +7,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -37,21 +37,21 @@ func TestNewDRV2605LDriver(t *testing.T) { if !ok { t.Errorf("NewDRV2605LDriver() should have returned a *DRV2605LDriver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "DRV2605L"), true) - gobottest.Assert(t, d.defaultAddress, 0x5a) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "DRV2605L")) + assert.Equal(t, 0x5a, d.defaultAddress) } func TestDRV2605LOptions(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option and // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". d := NewDRV2605LDriver(newI2cTestAdaptor(), WithBus(2)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) + assert.Equal(t, 2, d.GetBusOrDefault(1)) } func TestDRV2605LStart(t *testing.T) { d := NewDRV2605LDriver(newI2cTestAdaptor()) - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestDRV2605LHalt(t *testing.T) { @@ -62,33 +62,33 @@ func TestDRV2605LHalt(t *testing.T) { writeNewStandbyModeData := []byte{drv2605RegMode, 42 | drv2605Standby} d, a := initTestDRV2605LDriverWithStubbedAdaptor() a.written = []byte{} - gobottest.Assert(t, d.Halt(), nil) - gobottest.Assert(t, a.written, append(append(writeStopPlaybackData, readCurrentStandbyModeData), writeNewStandbyModeData...)) + assert.NoError(t, d.Halt()) + assert.Equal(t, append(append(writeStopPlaybackData, readCurrentStandbyModeData), writeNewStandbyModeData...), a.written) } func TestDRV2605LGetPause(t *testing.T) { d, _ := initTestDRV2605LDriverWithStubbedAdaptor() - gobottest.Assert(t, d.GetPauseWaveform(0), uint8(0x80)) - gobottest.Assert(t, d.GetPauseWaveform(1), uint8(0x81)) - gobottest.Assert(t, d.GetPauseWaveform(128), d.GetPauseWaveform(127)) + assert.Equal(t, uint8(0x80), d.GetPauseWaveform(0)) + assert.Equal(t, uint8(0x81), d.GetPauseWaveform(1)) + assert.Equal(t, d.GetPauseWaveform(127), d.GetPauseWaveform(128)) } func TestDRV2605LSequenceTermination(t *testing.T) { d, a := initTestDRV2605LDriverWithStubbedAdaptor() a.written = []byte{} - gobottest.Assert(t, d.SetSequence([]byte{1, 2}), nil) - gobottest.Assert(t, a.written, []byte{ + assert.NoError(t, d.SetSequence([]byte{1, 2})) + assert.Equal(t, []byte{ drv2605RegWaveSeq1, 1, drv2605RegWaveSeq2, 2, drv2605RegWaveSeq3, 0, - }) + }, a.written) } func TestDRV2605LSequenceTruncation(t *testing.T) { d, a := initTestDRV2605LDriverWithStubbedAdaptor() a.written = []byte{} - gobottest.Assert(t, d.SetSequence([]byte{1, 2, 3, 4, 5, 6, 7, 8, 99, 100}), nil) - gobottest.Assert(t, a.written, []byte{ + assert.NoError(t, d.SetSequence([]byte{1, 2, 3, 4, 5, 6, 7, 8, 99, 100})) + assert.Equal(t, []byte{ drv2605RegWaveSeq1, 1, drv2605RegWaveSeq2, 2, drv2605RegWaveSeq3, 3, @@ -97,12 +97,12 @@ func TestDRV2605LSequenceTruncation(t *testing.T) { drv2605RegWaveSeq6, 6, drv2605RegWaveSeq7, 7, drv2605RegWaveSeq8, 8, - }) + }, a.written) } func TestDRV2605LSetMode(t *testing.T) { d, _ := initTestDRV2605LDriverWithStubbedAdaptor() - gobottest.Assert(t, d.SetMode(DRV2605ModeIntTrig), nil) + assert.NoError(t, d.SetMode(DRV2605ModeIntTrig)) } func TestDRV2605LSetModeReadError(t *testing.T) { @@ -110,12 +110,12 @@ func TestDRV2605LSetModeReadError(t *testing.T) { a.i2cReadImpl = func(b []byte) (int, error) { return 0, errors.New("read error") } - gobottest.Assert(t, d.SetMode(DRV2605ModeIntTrig), errors.New("read error")) + assert.ErrorContains(t, d.SetMode(DRV2605ModeIntTrig), "read error") } func TestDRV2605LSetStandbyMode(t *testing.T) { d, _ := initTestDRV2605LDriverWithStubbedAdaptor() - gobottest.Assert(t, d.SetStandbyMode(true), nil) + assert.NoError(t, d.SetStandbyMode(true)) } func TestDRV2605LSetStandbyModeReadError(t *testing.T) { @@ -123,15 +123,15 @@ func TestDRV2605LSetStandbyModeReadError(t *testing.T) { a.i2cReadImpl = func(b []byte) (int, error) { return 0, errors.New("read error") } - gobottest.Assert(t, d.SetStandbyMode(true), errors.New("read error")) + assert.ErrorContains(t, d.SetStandbyMode(true), "read error") } func TestDRV2605LSelectLibrary(t *testing.T) { d, _ := initTestDRV2605LDriverWithStubbedAdaptor() - gobottest.Assert(t, d.SelectLibrary(1), nil) + assert.NoError(t, d.SelectLibrary(1)) } func TestDRV2605LGo(t *testing.T) { d, _ := initTestDRV2605LDriverWithStubbedAdaptor() - gobottest.Assert(t, d.Go(), nil) + assert.NoError(t, d.Go()) } diff --git a/drivers/i2c/generic_driver_test.go b/drivers/i2c/generic_driver_test.go index 44d6d94d6..fdb490e69 100644 --- a/drivers/i2c/generic_driver_test.go +++ b/drivers/i2c/generic_driver_test.go @@ -4,8 +4,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*GenericDriver)(nil) @@ -20,6 +20,6 @@ func TestNewGenericDriver(t *testing.T) { if !ok { t.Errorf("NewGenericDriver() should have returned a *GenericDriver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "GenericI2C"), true) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "GenericI2C")) } diff --git a/drivers/i2c/grove_drivers.go b/drivers/i2c/grove_drivers.go index a5459951e..f54ff16fb 100644 --- a/drivers/i2c/grove_drivers.go +++ b/drivers/i2c/grove_drivers.go @@ -15,12 +15,13 @@ type GroveAccelerometerDriver struct { // NewGroveLcdDriver creates a new driver with specified i2c interface. // Params: -// conn Connector - the Adaptor to use with this Driver +// +// conn Connector - the Adaptor to use with this Driver // // Optional params: -// i2c.WithBus(int): bus to use with this driver -// i2c.WithAddress(int): address to use with this driver // +// i2c.WithBus(int): bus to use with this driver +// i2c.WithAddress(int): address to use with this driver func NewGroveLcdDriver(a Connector, options ...func(Config)) *GroveLcdDriver { lcd := &GroveLcdDriver{ JHD1313M1Driver: NewJHD1313M1Driver(a), @@ -35,12 +36,13 @@ func NewGroveLcdDriver(a Connector, options ...func(Config)) *GroveLcdDriver { // NewGroveAccelerometerDriver creates a new driver with specified i2c interface // Params: -// conn Connector - the Adaptor to use with this Driver +// +// conn Connector - the Adaptor to use with this Driver // // Optional params: -// i2c.WithBus(int): bus to use with this driver -// i2c.WithAddress(int): address to use with this driver // +// i2c.WithBus(int): bus to use with this driver +// i2c.WithAddress(int): address to use with this driver func NewGroveAccelerometerDriver(a Connector, options ...func(Config)) *GroveAccelerometerDriver { mma := &GroveAccelerometerDriver{ MMA7660Driver: NewMMA7660Driver(a), diff --git a/drivers/i2c/grove_drivers_test.go b/drivers/i2c/grove_drivers_test.go index 2d94f7711..19f755897 100644 --- a/drivers/i2c/grove_drivers_test.go +++ b/drivers/i2c/grove_drivers_test.go @@ -4,12 +4,14 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) -var _ gobot.Driver = (*GroveLcdDriver)(nil) -var _ gobot.Driver = (*GroveAccelerometerDriver)(nil) +var ( + _ gobot.Driver = (*GroveLcdDriver)(nil) + _ gobot.Driver = (*GroveAccelerometerDriver)(nil) +) func initTestGroveLcdDriver() (driver *GroveLcdDriver) { driver, _ = initGroveLcdDriverWithStubbedAdaptor() @@ -33,24 +35,24 @@ func initGroveAccelerometerDriverWithStubbedAdaptor() (*GroveAccelerometerDriver func TestGroveLcdDriverName(t *testing.T) { g := initTestGroveLcdDriver() - gobottest.Refute(t, g.Connection(), nil) - gobottest.Assert(t, strings.HasPrefix(g.Name(), "JHD1313M1"), true) + assert.NotNil(t, g.Connection()) + assert.True(t, strings.HasPrefix(g.Name(), "JHD1313M1")) } func TestLcdDriverWithAddress(t *testing.T) { adaptor := newI2cTestAdaptor() g := NewGroveLcdDriver(adaptor, WithAddress(0x66)) - gobottest.Assert(t, g.GetAddressOrDefault(0x33), 0x66) + assert.Equal(t, 0x66, g.GetAddressOrDefault(0x33)) } func TestGroveAccelerometerDriverName(t *testing.T) { g := initTestGroveAccelerometerDriver() - gobottest.Refute(t, g.Connection(), nil) - gobottest.Assert(t, strings.HasPrefix(g.Name(), "MMA7660"), true) + assert.NotNil(t, g.Connection()) + assert.True(t, strings.HasPrefix(g.Name(), "MMA7660")) } func TestGroveAccelerometerDriverWithAddress(t *testing.T) { adaptor := newI2cTestAdaptor() g := NewGroveAccelerometerDriver(adaptor, WithAddress(0x66)) - gobottest.Assert(t, g.GetAddressOrDefault(0x33), 0x66) + assert.Equal(t, 0x66, g.GetAddressOrDefault(0x33)) } diff --git a/drivers/i2c/grovepi_driver.go b/drivers/i2c/grovepi_driver.go index fea0dcbbd..bc5a799a4 100644 --- a/drivers/i2c/grovepi_driver.go +++ b/drivers/i2c/grovepi_driver.go @@ -29,9 +29,8 @@ const ( // GrovePiDriver is a driver for the GrovePi+ for I²C bus interface. // https://www.dexterindustries.com/grovepi/ // -// To use this driver with the GrovePi, it must be running the firmware >= 1.4.0 and and the system version >=3. +// To use this driver with the GrovePi, it must be running the firmware >= 1.4.0 and the system version >=3. // https://github.com/DexterInd/GrovePi/blob/master/README.md -// type GrovePiDriver struct { *Driver pins map[int]string @@ -39,12 +38,13 @@ type GrovePiDriver struct { // NewGrovePiDriver creates a new driver with specified i2c interface // Params: -// conn Connector - the Adaptor to use with this Driver +// +// conn Connector - the Adaptor to use with this Driver // // Optional params: -// i2c.WithBus(int): bus to use with this driver -// i2c.WithAddress(int): address to use with this driver // +// i2c.WithBus(int): bus to use with this driver +// i2c.WithAddress(int): address to use with this driver func NewGrovePiDriver(c Connector, options ...func(Config)) *GrovePiDriver { d := &GrovePiDriver{ Driver: NewDriver(c, "GrovePi", grovePiDefaultAddress), diff --git a/drivers/i2c/grovepi_driver_test.go b/drivers/i2c/grovepi_driver_test.go index dad364537..d50abc707 100644 --- a/drivers/i2c/grovepi_driver_test.go +++ b/drivers/i2c/grovepi_driver_test.go @@ -5,10 +5,10 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" "gobot.io/x/gobot/v2/drivers/aio" "gobot.io/x/gobot/v2/drivers/gpio" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -41,22 +41,22 @@ func TestNewGrovePiDriver(t *testing.T) { if !ok { t.Errorf("NewGrovePiDriver() should have returned a *GrovePiDriver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "GrovePi"), true) - gobottest.Assert(t, d.defaultAddress, 0x04) - gobottest.Refute(t, d.pins, nil) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "GrovePi")) + assert.Equal(t, 0x04, d.defaultAddress) + assert.NotNil(t, d.pins) } func TestGrovePiOptions(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option and // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". d := NewGrovePiDriver(newI2cTestAdaptor(), WithBus(2)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) + assert.Equal(t, 2, d.GetBusOrDefault(1)) } func TestGrovePiSomeRead(t *testing.T) { // arrange - var tests = map[string]struct { + tests := map[string]struct { usedPin int wantWritten []uint8 simResponse [][]uint8 @@ -166,20 +166,20 @@ func TestGrovePiSomeRead(t *testing.T) { return } // assert - gobottest.Assert(t, err, tc.wantErr) - gobottest.Assert(t, a.written, tc.wantWritten) - gobottest.Assert(t, numCallsRead, len(tc.simResponse)) - gobottest.Assert(t, got, tc.wantResult) - gobottest.Assert(t, gotF1, tc.wantResultF1) - gobottest.Assert(t, gotF2, tc.wantResultF2) - gobottest.Assert(t, gotString, tc.wantResultString) + assert.Equal(t, tc.wantErr, err) + assert.Equal(t, tc.wantWritten, a.written) + assert.Equal(t, len(tc.simResponse), numCallsRead) + assert.Equal(t, tc.wantResult, got) + assert.Equal(t, tc.wantResultF1, gotF1) + assert.Equal(t, tc.wantResultF2, gotF2) + assert.Equal(t, tc.wantResultString, gotString) }) } } func TestGrovePiSomeWrite(t *testing.T) { // arrange - var tests = map[string]struct { + tests := map[string]struct { usedPin int usedValue int wantWritten []uint8 @@ -219,16 +219,16 @@ func TestGrovePiSomeWrite(t *testing.T) { return } // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, a.written, tc.wantWritten) + assert.NoError(t, err) + assert.Equal(t, tc.wantWritten, a.written) }) } } func TestGrovePi_getPin(t *testing.T) { - gobottest.Assert(t, getPin("a1"), "1") - gobottest.Assert(t, getPin("A16"), "16") - gobottest.Assert(t, getPin("D3"), "3") - gobottest.Assert(t, getPin("d22"), "22") - gobottest.Assert(t, getPin("22"), "22") + assert.Equal(t, "1", getPin("a1")) + assert.Equal(t, "16", getPin("A16")) + assert.Equal(t, "3", getPin("D3")) + assert.Equal(t, "22", getPin("d22")) + assert.Equal(t, "22", getPin("22")) } diff --git a/drivers/i2c/hmc5883l_driver.go b/drivers/i2c/hmc5883l_driver.go index f2acbd34a..395ab8431 100644 --- a/drivers/i2c/hmc5883l_driver.go +++ b/drivers/i2c/hmc5883l_driver.go @@ -109,16 +109,17 @@ var hmc5883lGainBits = map[float64]int{ // NewHMC5883LDriver creates a new driver with specified i2c interface // Params: -// c Connector - the Adaptor to use with this Driver +// +// c Connector - the Adaptor to use with this Driver // // Optional params: -// i2c.WithBus(int): bus to use with this driver -// i2c.WithAddress(int): address to use with this driver -// i2c.WithHMC5883LSamplesAveraged(int) -// i2c.WithHMC5883LDataOutputRate(int) -// i2c.WithHMC5883LMeasurementFlow(int) -// i2c.WithHMC5883LGain(int) // +// i2c.WithBus(int): bus to use with this driver +// i2c.WithAddress(int): address to use with this driver +// i2c.WithHMC5883LSamplesAveraged(int) +// i2c.WithHMC5883LDataOutputRate(int) +// i2c.WithHMC5883LMeasurementFlow(int) +// i2c.WithHMC5883LGain(int) func NewHMC5883LDriver(c Connector, options ...func(Config)) *HMC5883LDriver { h := &HMC5883LDriver{ Driver: NewDriver(c, "HMC5883L", hmc5883lDefaultAddress), diff --git a/drivers/i2c/hmc5883l_driver_test.go b/drivers/i2c/hmc5883l_driver_test.go index a7a88d9b0..9af18c1c7 100644 --- a/drivers/i2c/hmc5883l_driver_test.go +++ b/drivers/i2c/hmc5883l_driver_test.go @@ -4,8 +4,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -23,45 +23,45 @@ func TestNewHMC5883LDriver(t *testing.T) { if !ok { t.Errorf("NewHMC5883LDriver() should have returned a *HMC5883LDriver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.name, "HMC5883L"), true) - gobottest.Assert(t, d.defaultAddress, 0x1E) - gobottest.Assert(t, d.samplesAvg, uint8(8)) - gobottest.Assert(t, d.outputRate, uint32(15000)) - gobottest.Assert(t, d.applyBias, int8(0)) - gobottest.Assert(t, d.measurementMode, 0) - gobottest.Assert(t, d.gain, 390.0) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.name, "HMC5883L")) + assert.Equal(t, 0x1E, d.defaultAddress) + assert.Equal(t, uint8(8), d.samplesAvg) + assert.Equal(t, uint32(15000), d.outputRate) + assert.Equal(t, int8(0), d.applyBias) + assert.Equal(t, 0, d.measurementMode) + assert.Equal(t, 390.0, d.gain) } func TestHMC5883LOptions(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option and // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". d := NewHMC5883LDriver(newI2cTestAdaptor(), WithBus(2), WithHMC5883LSamplesAveraged(4)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) - gobottest.Assert(t, d.samplesAvg, uint8(4)) + assert.Equal(t, 2, d.GetBusOrDefault(1)) + assert.Equal(t, uint8(4), d.samplesAvg) } func TestHMC5883LWithHMC5883LDataOutputRate(t *testing.T) { d := NewHMC5883LDriver(newI2cTestAdaptor()) WithHMC5883LDataOutputRate(7500)(d) - gobottest.Assert(t, d.outputRate, uint32(7500)) + assert.Equal(t, uint32(7500), d.outputRate) } func TestHMC5883LWithHMC5883LApplyBias(t *testing.T) { d := NewHMC5883LDriver(newI2cTestAdaptor()) WithHMC5883LApplyBias(-1)(d) - gobottest.Assert(t, d.applyBias, int8(-1)) + assert.Equal(t, int8(-1), d.applyBias) } func TestHMC5883LWithHMC5883LGain(t *testing.T) { d := NewHMC5883LDriver(newI2cTestAdaptor()) WithHMC5883LGain(230)(d) - gobottest.Assert(t, d.gain, 230.0) + assert.Equal(t, 230.0, d.gain) } func TestHMC5883LRead(t *testing.T) { // arrange - var tests = map[string]struct { + tests := map[string]struct { inputX []uint8 inputY []uint8 inputZ []uint8 @@ -121,10 +121,10 @@ func TestHMC5883LRead(t *testing.T) { // act gotX, gotY, gotZ, err := d.Read() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, gotX, tc.wantX) - gobottest.Assert(t, gotY, tc.wantY) - gobottest.Assert(t, gotZ, tc.wantZ) + assert.NoError(t, err) + assert.Equal(t, tc.wantX, gotX) + assert.Equal(t, tc.wantY, gotY) + assert.Equal(t, tc.wantZ, gotZ) }) } } @@ -136,7 +136,7 @@ func TestHMC5883L_readRawData(t *testing.T) { // * apply two's complement converter // // arrange - var tests = map[string]struct { + tests := map[string]struct { inputX []uint8 inputY []uint8 inputZ []uint8 @@ -177,13 +177,13 @@ func TestHMC5883L_readRawData(t *testing.T) { // act gotX, gotY, gotZ, err := d.readRawData() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, gotX, tc.wantX) - gobottest.Assert(t, gotY, tc.wantY) - gobottest.Assert(t, gotZ, tc.wantZ) - gobottest.Assert(t, numCallsRead, 1) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], uint8(hmc5883lAxisX)) + assert.NoError(t, err) + assert.Equal(t, tc.wantX, gotX) + assert.Equal(t, tc.wantY, gotY) + assert.Equal(t, tc.wantZ, gotZ) + assert.Equal(t, 1, numCallsRead) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, uint8(hmc5883lAxisX), a.written[0]) }) } } @@ -203,12 +203,12 @@ func TestHMC5883L_initialize(t *testing.T) { // act, assert - initialize() must be called on Start() err := d.Start() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 6) - gobottest.Assert(t, a.written[0], uint8(hmc5883lRegA)) - gobottest.Assert(t, a.written[1], wantRegA) - gobottest.Assert(t, a.written[2], uint8(hmc5883lRegB)) - gobottest.Assert(t, a.written[3], wantRegB) - gobottest.Assert(t, a.written[4], uint8(hmc5883lRegMode)) - gobottest.Assert(t, a.written[5], wantRegM) + assert.NoError(t, err) + assert.Equal(t, 6, len(a.written)) + assert.Equal(t, uint8(hmc5883lRegA), a.written[0]) + assert.Equal(t, wantRegA, a.written[1]) + assert.Equal(t, uint8(hmc5883lRegB), a.written[2]) + assert.Equal(t, wantRegB, a.written[3]) + assert.Equal(t, uint8(hmc5883lRegMode), a.written[4]) + assert.Equal(t, wantRegM, a.written[5]) } diff --git a/drivers/i2c/hmc6352_driver.go b/drivers/i2c/hmc6352_driver.go index 6c9d8544c..8dd8c43f3 100644 --- a/drivers/i2c/hmc6352_driver.go +++ b/drivers/i2c/hmc6352_driver.go @@ -9,12 +9,13 @@ type HMC6352Driver struct { // NewHMC6352Driver creates a new driver with specified i2c interface // Params: -// c Connector - the Adaptor to use with this Driver +// +// c Connector - the Adaptor to use with this Driver // // Optional params: -// i2c.WithBus(int): bus to use with this driver -// i2c.WithAddress(int): address to use with this driver // +// i2c.WithBus(int): bus to use with this driver +// i2c.WithAddress(int): address to use with this driver func NewHMC6352Driver(c Connector, options ...func(Config)) *HMC6352Driver { h := &HMC6352Driver{ Driver: NewDriver(c, "HMC6352", hmc6352DefaultAddress), diff --git a/drivers/i2c/hmc6352_driver_test.go b/drivers/i2c/hmc6352_driver_test.go index fa2e01c0f..7061a905a 100644 --- a/drivers/i2c/hmc6352_driver_test.go +++ b/drivers/i2c/hmc6352_driver_test.go @@ -5,8 +5,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -28,26 +28,26 @@ func TestNewHMC6352Driver(t *testing.T) { if !ok { t.Errorf("NewHMC6352Driver() should have returned a *HMC6352Driver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "HMC6352"), true) - gobottest.Assert(t, d.defaultAddress, 0x21) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "HMC6352")) + assert.Equal(t, 0x21, d.defaultAddress) } func TestHMC6352Options(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option and // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". d := NewHMC6352Driver(newI2cTestAdaptor(), WithBus(2)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) + assert.Equal(t, 2, d.GetBusOrDefault(1)) } func TestHMC6352Start(t *testing.T) { d := NewHMC6352Driver(newI2cTestAdaptor()) - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestHMC6352Halt(t *testing.T) { d, _ := initTestHMC6352DriverWithStubbedAdaptor() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestHMC6352Heading(t *testing.T) { @@ -59,7 +59,7 @@ func TestHMC6352Heading(t *testing.T) { } heading, _ := d.Heading() - gobottest.Assert(t, heading, uint16(2534)) + assert.Equal(t, uint16(2534), heading) // when len(data) is not 2 d, a = initTestHMC6352DriverWithStubbedAdaptor() @@ -69,8 +69,8 @@ func TestHMC6352Heading(t *testing.T) { } heading, err := d.Heading() - gobottest.Assert(t, heading, uint16(0)) - gobottest.Assert(t, err, ErrNotEnoughBytes) + assert.Equal(t, uint16(0), heading) + assert.Equal(t, ErrNotEnoughBytes, err) // when read error d, a = initTestHMC6352DriverWithStubbedAdaptor() @@ -79,8 +79,8 @@ func TestHMC6352Heading(t *testing.T) { } heading, err = d.Heading() - gobottest.Assert(t, heading, uint16(0)) - gobottest.Assert(t, err, errors.New("read error")) + assert.Equal(t, uint16(0), heading) + assert.ErrorContains(t, err, "read error") // when write error d, a = initTestHMC6352DriverWithStubbedAdaptor() @@ -89,6 +89,6 @@ func TestHMC6352Heading(t *testing.T) { } heading, err = d.Heading() - gobottest.Assert(t, heading, uint16(0)) - gobottest.Assert(t, err, errors.New("write error")) + assert.Equal(t, uint16(0), heading) + assert.ErrorContains(t, err, "write error") } diff --git a/drivers/i2c/i2c_config_test.go b/drivers/i2c/i2c_config_test.go index fac9087ae..7c9a2fbb2 100644 --- a/drivers/i2c/i2c_config_test.go +++ b/drivers/i2c/i2c_config_test.go @@ -3,7 +3,7 @@ package i2c import ( "testing" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) func TestNewConfig(t *testing.T) { @@ -14,8 +14,8 @@ func TestNewConfig(t *testing.T) { if !ok { t.Errorf("NewConfig() should have returned a *i2cConfig") } - gobottest.Assert(t, c.bus, BusNotInitialized) - gobottest.Assert(t, c.address, AddressNotInitialized) + assert.Equal(t, BusNotInitialized, c.bus) + assert.Equal(t, AddressNotInitialized, c.address) } func TestWithBus(t *testing.T) { @@ -24,7 +24,7 @@ func TestWithBus(t *testing.T) { // act c.SetBus(0x23) // assert - gobottest.Assert(t, c.(*i2cConfig).bus, 0x23) + assert.Equal(t, 0x23, c.(*i2cConfig).bus) } func TestWithAddress(t *testing.T) { @@ -33,11 +33,11 @@ func TestWithAddress(t *testing.T) { // act c.SetAddress(0x24) // assert - gobottest.Assert(t, c.(*i2cConfig).address, 0x24) + assert.Equal(t, 0x24, c.(*i2cConfig).address) } func TestGetBusOrDefaultWithBusOption(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { init int bus int want int @@ -53,13 +53,13 @@ func TestGetBusOrDefaultWithBusOption(t *testing.T) { WithBus(tc.init)(c) got := c.GetBusOrDefault(tc.bus) // assert - gobottest.Assert(t, got, tc.want) + assert.Equal(t, tc.want, got) }) } } func TestGetAddressOrDefaultWithAddressOption(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { init int address int want int @@ -75,7 +75,7 @@ func TestGetAddressOrDefaultWithAddressOption(t *testing.T) { WithAddress(tc.init)(c) got := c.GetAddressOrDefault(tc.address) // assert - gobottest.Assert(t, got, tc.want) + assert.Equal(t, tc.want, got) }) } } diff --git a/drivers/i2c/i2c_connection_test.go b/drivers/i2c/i2c_connection_test.go index 7e7600742..e4a610e95 100644 --- a/drivers/i2c/i2c_connection_test.go +++ b/drivers/i2c/i2c_connection_test.go @@ -4,13 +4,11 @@ package i2c import ( - "errors" "testing" - "unsafe" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" "gobot.io/x/gobot/v2/system" ) @@ -72,130 +70,130 @@ func initI2CDeviceAddressError() gobot.I2cSystemDevicer { func TestI2CAddress(t *testing.T) { c := NewConnection(initI2CDevice(), 0x66) - gobottest.Assert(t, c.address, 0x66) + assert.Equal(t, 0x66, c.address) } func TestI2CClose(t *testing.T) { c := NewConnection(initI2CDevice(), 0x06) - gobottest.Assert(t, c.Close(), nil) + assert.NoError(t, c.Close()) } func TestI2CRead(t *testing.T) { c := NewConnection(initI2CDevice(), 0x06) i, _ := c.Read([]byte{}) - gobottest.Assert(t, i, 0) + assert.Equal(t, 0, i) } func TestI2CReadAddressError(t *testing.T) { c := NewConnection(initI2CDeviceAddressError(), 0x06) _, err := c.Read([]byte{}) - gobottest.Assert(t, err, errors.New("Setting address failed with syscall.Errno operation not permitted")) + assert.ErrorContains(t, err, "Setting address failed with syscall.Errno operation not permitted") } func TestI2CWrite(t *testing.T) { c := NewConnection(initI2CDevice(), 0x06) i, _ := c.Write([]byte{0x01}) - gobottest.Assert(t, i, 1) + assert.Equal(t, 1, i) } func TestI2CWriteAddressError(t *testing.T) { c := NewConnection(initI2CDeviceAddressError(), 0x06) _, err := c.Write([]byte{0x01}) - gobottest.Assert(t, err, errors.New("Setting address failed with syscall.Errno operation not permitted")) + assert.ErrorContains(t, err, "Setting address failed with syscall.Errno operation not permitted") } func TestI2CReadByte(t *testing.T) { c := NewConnection(initI2CDevice(), 0x06) v, _ := c.ReadByte() - gobottest.Assert(t, v, uint8(0xFC)) + assert.Equal(t, uint8(0xFC), v) } func TestI2CReadByteAddressError(t *testing.T) { c := NewConnection(initI2CDeviceAddressError(), 0x06) _, err := c.ReadByte() - gobottest.Assert(t, err, errors.New("Setting address failed with syscall.Errno operation not permitted")) + assert.ErrorContains(t, err, "Setting address failed with syscall.Errno operation not permitted") } func TestI2CReadByteData(t *testing.T) { c := NewConnection(initI2CDevice(), 0x06) v, _ := c.ReadByteData(0x01) - gobottest.Assert(t, v, uint8(0xFD)) + assert.Equal(t, uint8(0xFD), v) } func TestI2CReadByteDataAddressError(t *testing.T) { c := NewConnection(initI2CDeviceAddressError(), 0x06) _, err := c.ReadByteData(0x01) - gobottest.Assert(t, err, errors.New("Setting address failed with syscall.Errno operation not permitted")) + assert.ErrorContains(t, err, "Setting address failed with syscall.Errno operation not permitted") } func TestI2CReadWordData(t *testing.T) { c := NewConnection(initI2CDevice(), 0x06) v, _ := c.ReadWordData(0x01) - gobottest.Assert(t, v, uint16(0xFFFE)) + assert.Equal(t, uint16(0xFFFE), v) } func TestI2CReadWordDataAddressError(t *testing.T) { c := NewConnection(initI2CDeviceAddressError(), 0x06) _, err := c.ReadWordData(0x01) - gobottest.Assert(t, err, errors.New("Setting address failed with syscall.Errno operation not permitted")) + assert.ErrorContains(t, err, "Setting address failed with syscall.Errno operation not permitted") } func TestI2CWriteByte(t *testing.T) { c := NewConnection(initI2CDevice(), 0x06) err := c.WriteByte(0x01) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) } func TestI2CWriteByteAddressError(t *testing.T) { c := NewConnection(initI2CDeviceAddressError(), 0x06) err := c.WriteByte(0x01) - gobottest.Assert(t, err, errors.New("Setting address failed with syscall.Errno operation not permitted")) + assert.ErrorContains(t, err, "Setting address failed with syscall.Errno operation not permitted") } func TestI2CWriteByteData(t *testing.T) { c := NewConnection(initI2CDevice(), 0x06) err := c.WriteByteData(0x01, 0x01) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) } func TestI2CWriteByteDataAddressError(t *testing.T) { c := NewConnection(initI2CDeviceAddressError(), 0x06) err := c.WriteByteData(0x01, 0x01) - gobottest.Assert(t, err, errors.New("Setting address failed with syscall.Errno operation not permitted")) + assert.ErrorContains(t, err, "Setting address failed with syscall.Errno operation not permitted") } func TestI2CWriteWordData(t *testing.T) { c := NewConnection(initI2CDevice(), 0x06) err := c.WriteWordData(0x01, 0x01) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) } func TestI2CWriteWordDataAddressError(t *testing.T) { c := NewConnection(initI2CDeviceAddressError(), 0x06) err := c.WriteWordData(0x01, 0x01) - gobottest.Assert(t, err, errors.New("Setting address failed with syscall.Errno operation not permitted")) + assert.ErrorContains(t, err, "Setting address failed with syscall.Errno operation not permitted") } func TestI2CWriteBlockData(t *testing.T) { c := NewConnection(initI2CDevice(), 0x06) err := c.WriteBlockData(0x01, []byte{0x01, 0x02}) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) } func TestI2CWriteBlockDataAddressError(t *testing.T) { c := NewConnection(initI2CDeviceAddressError(), 0x06) err := c.WriteBlockData(0x01, []byte{0x01, 0x02}) - gobottest.Assert(t, err, errors.New("Setting address failed with syscall.Errno operation not permitted")) + assert.ErrorContains(t, err, "Setting address failed with syscall.Errno operation not permitted") } func Test_setBit(t *testing.T) { var expectedVal uint8 = 129 actualVal := setBit(1, 7) - gobottest.Assert(t, expectedVal, actualVal) + assert.Equal(t, actualVal, expectedVal) } func Test_clearBit(t *testing.T) { var expectedVal uint8 actualVal := clearBit(128, 7) - gobottest.Assert(t, expectedVal, actualVal) + assert.Equal(t, actualVal, expectedVal) } diff --git a/drivers/i2c/i2c_driver.go b/drivers/i2c/i2c_driver.go index 238e7ac45..88c26ab79 100644 --- a/drivers/i2c/i2c_driver.go +++ b/drivers/i2c/i2c_driver.go @@ -91,7 +91,7 @@ func (d *Driver) Start() error { var err error bus := d.GetBusOrDefault(d.connector.DefaultI2cBus()) - address := d.GetAddressOrDefault(int(d.defaultAddress)) + address := d.GetAddressOrDefault(d.defaultAddress) if d.connection, err = d.connector.GetI2cConnection(address, bus); err != nil { return err diff --git a/drivers/i2c/i2c_driver_test.go b/drivers/i2c/i2c_driver_test.go index 3fed2a785..dd1addc2f 100644 --- a/drivers/i2c/i2c_driver_test.go +++ b/drivers/i2c/i2c_driver_test.go @@ -1,12 +1,10 @@ package i2c import ( - "errors" - "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*Driver)(nil) @@ -32,15 +30,15 @@ func TestNewDriver(t *testing.T) { if !ok { t.Errorf("NewDriver() should have returned a *Driver") } - gobottest.Assert(t, strings.Contains(d.name, "I2C_BASIC"), true) - gobottest.Assert(t, d.defaultAddress, 0x15) - gobottest.Assert(t, d.connector, a) - gobottest.Assert(t, d.connection, nil) - gobottest.Assert(t, d.afterStart(), nil) - gobottest.Assert(t, d.beforeHalt(), nil) - gobottest.Refute(t, d.Config, nil) - gobottest.Refute(t, d.Commander, nil) - gobottest.Refute(t, d.mutex, nil) + assert.Contains(t, d.name, "I2C_BASIC") + assert.Equal(t, 0x15, d.defaultAddress) + assert.Equal(t, a, d.connector) + assert.Nil(t, d.connection) + assert.NoError(t, d.afterStart()) + assert.NoError(t, d.beforeHalt()) + assert.NotNil(t, d.Config) + assert.NotNil(t, d.Commander) + assert.NotNil(t, d.mutex) } func TestSetName(t *testing.T) { @@ -49,22 +47,22 @@ func TestSetName(t *testing.T) { // act d.SetName("TESTME") // assert - gobottest.Assert(t, d.Name(), "TESTME") + assert.Equal(t, "TESTME", d.Name()) } func TestConnection(t *testing.T) { // arrange d := initTestDriver() // act, assert - gobottest.Refute(t, d.Connection(), nil) + assert.NotNil(t, d.Connection()) } func TestStart(t *testing.T) { // arrange d, a := initDriverWithStubbedAdaptor() // act, assert - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, 0x15, a.address) + assert.NoError(t, d.Start()) + assert.Equal(t, a.address, 0x15) } func TestStartConnectError(t *testing.T) { @@ -72,14 +70,14 @@ func TestStartConnectError(t *testing.T) { d, a := initDriverWithStubbedAdaptor() a.Testi2cConnectErr(true) // act, assert - gobottest.Assert(t, d.Start(), errors.New("Invalid i2c connection")) + assert.ErrorContains(t, d.Start(), "Invalid i2c connection") } func TestHalt(t *testing.T) { // arrange d := initTestDriver() // act, assert - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestWrite(t *testing.T) { @@ -100,10 +98,10 @@ func TestWrite(t *testing.T) { // act err := d.Write(address, value) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, numCallsWrite, 1) - gobottest.Assert(t, a.written[0], wantAddress) - gobottest.Assert(t, a.written[1], uint8(value)) + assert.NoError(t, err) + assert.Equal(t, 1, numCallsWrite) + assert.Equal(t, wantAddress, a.written[0]) + assert.Equal(t, uint8(value), a.written[1]) } func TestRead(t *testing.T) { @@ -131,9 +129,9 @@ func TestRead(t *testing.T) { // act val, err := d.Read(address) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, val, int(want)) - gobottest.Assert(t, numCallsWrite, 1) - gobottest.Assert(t, a.written[0], wantAddress) - gobottest.Assert(t, numCallsRead, 1) + assert.NoError(t, err) + assert.Equal(t, int(want), val) + assert.Equal(t, 1, numCallsWrite) + assert.Equal(t, wantAddress, a.written[0]) + assert.Equal(t, 1, numCallsRead) } diff --git a/drivers/i2c/ina3221_driver.go b/drivers/i2c/ina3221_driver.go index 1624325fd..6ff5ab7a2 100644 --- a/drivers/i2c/ina3221_driver.go +++ b/drivers/i2c/ina3221_driver.go @@ -149,7 +149,7 @@ func (i *INA3221Driver) readWordFromRegister(reg uint8) (uint16, error) { return 0, err } - return uint16(((val & 0x00FF) << 8) | ((val & 0xFF00) >> 8)), nil + return ((val & 0x00FF) << 8) | ((val & 0xFF00) >> 8), nil } // initialize initializes the INA3221 device diff --git a/drivers/i2c/ina3221_driver_test.go b/drivers/i2c/ina3221_driver_test.go index 3564fd824..ae044fc9d 100644 --- a/drivers/i2c/ina3221_driver_test.go +++ b/drivers/i2c/ina3221_driver_test.go @@ -1,14 +1,12 @@ package i2c import ( - "testing" - "errors" - "strings" + "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -30,26 +28,26 @@ func TestNewINA3221Driver(t *testing.T) { if !ok { t.Error("NewINA3221Driver() should return a *INA3221Driver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "INA3221"), true) - gobottest.Assert(t, d.defaultAddress, 0x40) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "INA3221")) + assert.Equal(t, 0x40, d.defaultAddress) } func TestINA3221Options(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option and // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". d := NewINA3221Driver(newI2cTestAdaptor(), WithBus(2)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) + assert.Equal(t, 2, d.GetBusOrDefault(1)) } func TestINA3221Start(t *testing.T) { d := NewINA3221Driver(newI2cTestAdaptor()) - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestINA3221Halt(t *testing.T) { d, _ := initTestINA3221DriverWithStubbedAdaptor() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestINA3221GetBusVoltage(t *testing.T) { @@ -61,8 +59,8 @@ func TestINA3221GetBusVoltage(t *testing.T) { } v, err := d.GetBusVoltage(INA3221Channel1) - gobottest.Assert(t, v, float64(13.928)) - gobottest.Assert(t, err, nil) + assert.Equal(t, float64(13.928), v) + assert.NoError(t, err) } func TestINA3221GetBusVoltageReadError(t *testing.T) { @@ -72,7 +70,7 @@ func TestINA3221GetBusVoltageReadError(t *testing.T) { } _, err := d.GetBusVoltage(INA3221Channel1) - gobottest.Assert(t, err, errors.New("read error")) + assert.ErrorContains(t, err, "read error") } func TestINA3221GetShuntVoltage(t *testing.T) { @@ -84,8 +82,8 @@ func TestINA3221GetShuntVoltage(t *testing.T) { } v, err := d.GetShuntVoltage(INA3221Channel1) - gobottest.Assert(t, v, float64(7.48)) - gobottest.Assert(t, err, nil) + assert.Equal(t, float64(7.48), v) + assert.NoError(t, err) } func TestINA3221GetShuntVoltageReadError(t *testing.T) { @@ -95,7 +93,7 @@ func TestINA3221GetShuntVoltageReadError(t *testing.T) { } _, err := d.GetShuntVoltage(INA3221Channel1) - gobottest.Assert(t, err, errors.New("read error")) + assert.ErrorContains(t, err, "read error") } func TestINA3221GetCurrent(t *testing.T) { @@ -107,8 +105,8 @@ func TestINA3221GetCurrent(t *testing.T) { } v, err := d.GetCurrent(INA3221Channel1) - gobottest.Assert(t, v, float64(74.8)) - gobottest.Assert(t, err, nil) + assert.Equal(t, float64(74.8), v) + assert.NoError(t, err) } func TestINA3221CurrentReadError(t *testing.T) { @@ -118,7 +116,7 @@ func TestINA3221CurrentReadError(t *testing.T) { } _, err := d.GetCurrent(INA3221Channel1) - gobottest.Assert(t, err, errors.New("read error")) + assert.ErrorContains(t, err, "read error") } func TestINA3221GetLoadVoltage(t *testing.T) { @@ -132,8 +130,8 @@ func TestINA3221GetLoadVoltage(t *testing.T) { } v, err := d.GetLoadVoltage(INA3221Channel2) - gobottest.Assert(t, v, float64(13.935480)) - gobottest.Assert(t, err, nil) + assert.Equal(t, float64(13.935480), v) + assert.NoError(t, err) } func TestINA3221GetLoadVoltageReadError(t *testing.T) { @@ -143,5 +141,5 @@ func TestINA3221GetLoadVoltageReadError(t *testing.T) { } _, err := d.GetLoadVoltage(INA3221Channel2) - gobottest.Assert(t, err, errors.New("read error")) + assert.ErrorContains(t, err, "read error") } diff --git a/drivers/i2c/jhd1313m1_driver_test.go b/drivers/i2c/jhd1313m1_driver_test.go index 1c0c99fc9..f89efadbc 100644 --- a/drivers/i2c/jhd1313m1_driver_test.go +++ b/drivers/i2c/jhd1313m1_driver_test.go @@ -5,8 +5,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*JHD1313M1Driver)(nil) @@ -37,30 +37,30 @@ func TestNewJHD1313M1Driver(t *testing.T) { func TestJHD1313M1Driver(t *testing.T) { jhd := initTestJHD1313M1Driver() - gobottest.Refute(t, jhd.Connection(), nil) - gobottest.Assert(t, strings.HasPrefix(jhd.Name(), "JHD1313M1"), true) + assert.NotNil(t, jhd.Connection()) + assert.True(t, strings.HasPrefix(jhd.Name(), "JHD1313M1")) } func TestJHD1313MDriverSetName(t *testing.T) { d := initTestJHD1313M1Driver() d.SetName("TESTME") - gobottest.Assert(t, d.Name(), "TESTME") + assert.Equal(t, "TESTME", d.Name()) } func TestJHD1313MDriverOptions(t *testing.T) { d := NewJHD1313M1Driver(newI2cTestAdaptor(), WithBus(2)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) + assert.Equal(t, 2, d.GetBusOrDefault(1)) } func TestJHD1313MDriverStart(t *testing.T) { d := initTestJHD1313M1Driver() - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestJHD1313MStartConnectError(t *testing.T) { d, adaptor := initTestJHD1313M1DriverWithStubbedAdaptor() adaptor.Testi2cConnectErr(true) - gobottest.Assert(t, d.Start(), errors.New("Invalid i2c connection")) + assert.ErrorContains(t, d.Start(), "Invalid i2c connection") } func TestJHD1313MDriverStartWriteError(t *testing.T) { @@ -68,19 +68,19 @@ func TestJHD1313MDriverStartWriteError(t *testing.T) { adaptor.i2cWriteImpl = func([]byte) (int, error) { return 0, errors.New("write error") } - gobottest.Assert(t, d.Start(), errors.New("write error")) + assert.ErrorContains(t, d.Start(), "write error") } func TestJHD1313MDriverHalt(t *testing.T) { d := initTestJHD1313M1Driver() _ = d.Start() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestJHD1313MDriverSetRgb(t *testing.T) { d, _ := initTestJHD1313M1DriverWithStubbedAdaptor() _ = d.Start() - gobottest.Assert(t, d.SetRGB(0x00, 0x00, 0x00), nil) + assert.NoError(t, d.SetRGB(0x00, 0x00, 0x00)) } func TestJHD1313MDriverSetRgbError(t *testing.T) { @@ -90,13 +90,13 @@ func TestJHD1313MDriverSetRgbError(t *testing.T) { a.i2cWriteImpl = func([]byte) (int, error) { return 0, errors.New("write error") } - gobottest.Assert(t, d.SetRGB(0x00, 0x00, 0x00), errors.New("write error")) + assert.ErrorContains(t, d.SetRGB(0x00, 0x00, 0x00), "write error") } func TestJHD1313MDriverClear(t *testing.T) { d, _ := initTestJHD1313M1DriverWithStubbedAdaptor() _ = d.Start() - gobottest.Assert(t, d.Clear(), nil) + assert.NoError(t, d.Clear()) } func TestJHD1313MDriverClearError(t *testing.T) { @@ -106,19 +106,19 @@ func TestJHD1313MDriverClearError(t *testing.T) { a.i2cWriteImpl = func([]byte) (int, error) { return 0, errors.New("write error") } - gobottest.Assert(t, d.Clear(), errors.New("write error")) + assert.ErrorContains(t, d.Clear(), "write error") } func TestJHD1313MDriverHome(t *testing.T) { d, _ := initTestJHD1313M1DriverWithStubbedAdaptor() _ = d.Start() - gobottest.Assert(t, d.Home(), nil) + assert.NoError(t, d.Home()) } func TestJHD1313MDriverWrite(t *testing.T) { d, _ := initTestJHD1313M1DriverWithStubbedAdaptor() _ = d.Start() - gobottest.Assert(t, d.Write("Hello"), nil) + assert.NoError(t, d.Write("Hello")) } func TestJHD1313MDriverWriteError(t *testing.T) { @@ -128,13 +128,13 @@ func TestJHD1313MDriverWriteError(t *testing.T) { return 0, errors.New("write error") } - gobottest.Assert(t, d.Write("Hello"), errors.New("write error")) + assert.ErrorContains(t, d.Write("Hello"), "write error") } func TestJHD1313MDriverWriteTwoLines(t *testing.T) { d, _ := initTestJHD1313M1DriverWithStubbedAdaptor() _ = d.Start() - gobottest.Assert(t, d.Write("Hello\nthere"), nil) + assert.NoError(t, d.Write("Hello\nthere")) } func TestJHD1313MDriverWriteTwoLinesError(t *testing.T) { @@ -144,52 +144,52 @@ func TestJHD1313MDriverWriteTwoLinesError(t *testing.T) { a.i2cWriteImpl = func([]byte) (int, error) { return 0, errors.New("write error") } - gobottest.Assert(t, d.Write("Hello\nthere"), errors.New("write error")) + assert.ErrorContains(t, d.Write("Hello\nthere"), "write error") } func TestJHD1313MDriverSetPosition(t *testing.T) { d, _ := initTestJHD1313M1DriverWithStubbedAdaptor() _ = d.Start() - gobottest.Assert(t, d.SetPosition(2), nil) + assert.NoError(t, d.SetPosition(2)) } func TestJHD1313MDriverSetSecondLinePosition(t *testing.T) { d, _ := initTestJHD1313M1DriverWithStubbedAdaptor() _ = d.Start() - gobottest.Assert(t, d.SetPosition(18), nil) + assert.NoError(t, d.SetPosition(18)) } func TestJHD1313MDriverSetPositionInvalid(t *testing.T) { d, _ := initTestJHD1313M1DriverWithStubbedAdaptor() _ = d.Start() - gobottest.Assert(t, d.SetPosition(-1), jhd1313m1ErrInvalidPosition) - gobottest.Assert(t, d.SetPosition(32), jhd1313m1ErrInvalidPosition) + assert.Equal(t, jhd1313m1ErrInvalidPosition, d.SetPosition(-1)) + assert.Equal(t, jhd1313m1ErrInvalidPosition, d.SetPosition(32)) } func TestJHD1313MDriverScroll(t *testing.T) { d, _ := initTestJHD1313M1DriverWithStubbedAdaptor() _ = d.Start() - gobottest.Assert(t, d.Scroll(true), nil) + assert.NoError(t, d.Scroll(true)) } func TestJHD1313MDriverReverseScroll(t *testing.T) { d, _ := initTestJHD1313M1DriverWithStubbedAdaptor() _ = d.Start() - gobottest.Assert(t, d.Scroll(false), nil) + assert.NoError(t, d.Scroll(false)) } func TestJHD1313MDriverSetCustomChar(t *testing.T) { d, _ := initTestJHD1313M1DriverWithStubbedAdaptor() data := [8]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} _ = d.Start() - gobottest.Assert(t, d.SetCustomChar(0, data), nil) + assert.NoError(t, d.SetCustomChar(0, data)) } func TestJHD1313MDriverSetCustomCharError(t *testing.T) { d, _ := initTestJHD1313M1DriverWithStubbedAdaptor() data := [8]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} _ = d.Start() - gobottest.Assert(t, d.SetCustomChar(10, data), errors.New("can't set a custom character at a position greater than 7")) + assert.ErrorContains(t, d.SetCustomChar(10, data), "can't set a custom character at a position greater than 7") } func TestJHD1313MDriverSetCustomCharWriteError(t *testing.T) { @@ -200,7 +200,7 @@ func TestJHD1313MDriverSetCustomCharWriteError(t *testing.T) { return 0, errors.New("write error") } data := [8]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} - gobottest.Assert(t, d.SetCustomChar(0, data), errors.New("write error")) + assert.ErrorContains(t, d.SetCustomChar(0, data), "write error") } func TestJHD1313MDriverCommands(t *testing.T) { @@ -208,20 +208,20 @@ func TestJHD1313MDriverCommands(t *testing.T) { _ = d.Start() err := d.Command("SetRGB")(map[string]interface{}{"r": "1", "g": "1", "b": "1"}) - gobottest.Assert(t, err, nil) + assert.Nil(t, err) err = d.Command("Clear")(map[string]interface{}{}) - gobottest.Assert(t, err, nil) + assert.Nil(t, err) err = d.Command("Home")(map[string]interface{}{}) - gobottest.Assert(t, err, nil) + assert.Nil(t, err) err = d.Command("Write")(map[string]interface{}{"msg": "Hello"}) - gobottest.Assert(t, err, nil) + assert.Nil(t, err) err = d.Command("SetPosition")(map[string]interface{}{"pos": "1"}) - gobottest.Assert(t, err, nil) + assert.Nil(t, err) err = d.Command("Scroll")(map[string]interface{}{"lr": "true"}) - gobottest.Assert(t, err, nil) + assert.Nil(t, err) } diff --git a/drivers/i2c/l3gd20h_driver_test.go b/drivers/i2c/l3gd20h_driver_test.go index 892891698..9e1bf43f8 100644 --- a/drivers/i2c/l3gd20h_driver_test.go +++ b/drivers/i2c/l3gd20h_driver_test.go @@ -5,8 +5,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -33,21 +33,21 @@ func TestNewL3GD20HDriver(t *testing.T) { if !ok { t.Errorf("NewL3GD20HDriver() should have returned a *L3GD20HDriver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "L3GD20H"), true) - gobottest.Assert(t, d.defaultAddress, 0x6b) - gobottest.Assert(t, d.Scale(), L3GD20HScale250dps) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "L3GD20H")) + assert.Equal(t, 0x6b, d.defaultAddress) + assert.Equal(t, L3GD20HScale250dps, d.Scale()) } func TestL3GD20HOptions(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option. // Further tests for options can also be done by call of "WithOption(val)(d)". d := NewL3GD20HDriver(newI2cTestAdaptor(), WithBus(2)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) + assert.Equal(t, 2, d.GetBusOrDefault(1)) } func TestL3GD20HWithL3GD20HFullScaleRange(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { scale L3GD20HScale want uint8 }{ @@ -75,13 +75,13 @@ func TestL3GD20HWithL3GD20HFullScaleRange(t *testing.T) { // act WithL3GD20HFullScaleRange(tc.scale)(d) // assert - gobottest.Assert(t, d.scale, L3GD20HScale(tc.want)) + assert.Equal(t, L3GD20HScale(tc.want), d.scale) }) } } func TestL3GD20HScale(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { scale L3GD20HScale want uint8 }{ @@ -109,7 +109,7 @@ func TestL3GD20HScale(t *testing.T) { // act d.SetScale(tc.scale) // assert - gobottest.Assert(t, d.scale, L3GD20HScale(tc.want)) + assert.Equal(t, L3GD20HScale(tc.want), d.scale) }) } } @@ -130,10 +130,10 @@ func TestL3GD20HFullScaleRange(t *testing.T) { // act got, err := d.FullScaleRange() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], uint8(0x23)) - gobottest.Assert(t, got, readValue) + assert.NoError(t, err) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, uint8(0x23), a.written[0]) + assert.Equal(t, readValue, got) } func TestL3GD20HMeasurement(t *testing.T) { @@ -146,7 +146,7 @@ func TestL3GD20HMeasurement(t *testing.T) { // // data table according to data sheet AN4506 example in table 7, supplemented with FS limit values sensitivity := float32(0.00875) // FS=245 dps - var tests = map[string]struct { + tests := map[string]struct { gyroData []byte wantX float32 wantY float32 @@ -196,12 +196,12 @@ func TestL3GD20HMeasurement(t *testing.T) { // act x, y, z, err := d.XYZ() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], uint8(0xA8)) - gobottest.Assert(t, x, tc.wantX) - gobottest.Assert(t, y, tc.wantY) - gobottest.Assert(t, z, tc.wantZ) + assert.NoError(t, err) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, uint8(0xA8), a.written[0]) + assert.Equal(t, tc.wantX, x) + assert.Equal(t, tc.wantY, y) + assert.Equal(t, tc.wantZ, z) }) } } @@ -214,7 +214,7 @@ func TestL3GD20HMeasurementError(t *testing.T) { _ = d.Start() _, _, _, err := d.XYZ() - gobottest.Assert(t, err, errors.New("read error")) + assert.ErrorContains(t, err, "read error") } func TestL3GD20HMeasurementWriteError(t *testing.T) { @@ -223,7 +223,7 @@ func TestL3GD20HMeasurementWriteError(t *testing.T) { return 0, errors.New("write error") } _, _, _, err := d.XYZ() - gobottest.Assert(t, err, errors.New("write error")) + assert.ErrorContains(t, err, "write error") } func TestL3GD20H_initialize(t *testing.T) { @@ -250,11 +250,11 @@ func TestL3GD20H_initialize(t *testing.T) { // arrange, act - initialize() must be called on Start() _, a := initL3GD20HWithStubbedAdaptor() // assert - gobottest.Assert(t, len(a.written), 6) - gobottest.Assert(t, a.written[0], uint8(0x20)) - gobottest.Assert(t, a.written[1], uint8(0x00)) - gobottest.Assert(t, a.written[2], uint8(0x20)) - gobottest.Assert(t, a.written[3], uint8(0x0F)) - gobottest.Assert(t, a.written[4], uint8(0x23)) - gobottest.Assert(t, a.written[5], uint8(0x00)) + assert.Equal(t, 6, len(a.written)) + assert.Equal(t, uint8(0x20), a.written[0]) + assert.Equal(t, uint8(0x00), a.written[1]) + assert.Equal(t, uint8(0x20), a.written[2]) + assert.Equal(t, uint8(0x0F), a.written[3]) + assert.Equal(t, uint8(0x23), a.written[4]) + assert.Equal(t, uint8(0x00), a.written[5]) } diff --git a/drivers/i2c/lidarlite_driver.go b/drivers/i2c/lidarlite_driver.go index 698fb9dc6..79f7d7d40 100644 --- a/drivers/i2c/lidarlite_driver.go +++ b/drivers/i2c/lidarlite_driver.go @@ -14,12 +14,13 @@ type LIDARLiteDriver struct { // NewLIDARLiteDriver creates a new driver for the LIDARLite I2C LIDAR device. // // Params: -// c Connector - the Adaptor to use with this Driver +// +// c Connector - the Adaptor to use with this Driver // // Optional params: -// i2c.WithBus(int): bus to use with this driver -// i2c.WithAddress(int): address to use with this driver // +// i2c.WithBus(int): bus to use with this driver +// i2c.WithAddress(int): address to use with this driver func NewLIDARLiteDriver(c Connector, options ...func(Config)) *LIDARLiteDriver { l := &LIDARLiteDriver{ Driver: NewDriver(c, "LIDARLite", lidarliteDefaultAddress), diff --git a/drivers/i2c/lidarlite_driver_test.go b/drivers/i2c/lidarlite_driver_test.go index 9a570fb2c..ecae4a6ab 100644 --- a/drivers/i2c/lidarlite_driver_test.go +++ b/drivers/i2c/lidarlite_driver_test.go @@ -6,8 +6,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -34,26 +34,26 @@ func TestNewLIDARLiteDriver(t *testing.T) { if !ok { t.Errorf("NewLIDARLiteDriver() should have returned a *LIDARLiteDriver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "LIDARLite"), true) - gobottest.Assert(t, d.defaultAddress, 0x62) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "LIDARLite")) + assert.Equal(t, 0x62, d.defaultAddress) } func TestLIDARLiteDriverOptions(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option and // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". d := NewLIDARLiteDriver(newI2cTestAdaptor(), WithBus(2)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) + assert.Equal(t, 2, d.GetBusOrDefault(1)) } func TestLIDARLiteDriverStart(t *testing.T) { d := NewLIDARLiteDriver(newI2cTestAdaptor()) - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestLIDARLiteDriverHalt(t *testing.T) { d := initTestLIDARLiteDriver() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestLIDARLiteDriverDistance(t *testing.T) { @@ -72,8 +72,8 @@ func TestLIDARLiteDriverDistance(t *testing.T) { distance, err := d.Distance() - gobottest.Assert(t, err, nil) - gobottest.Assert(t, distance, int(25345)) + assert.NoError(t, err) + assert.Equal(t, int(25345), distance) // when insufficient bytes have been read d, a = initTestLIDARLiteDriverWithStubbedAdaptor() @@ -82,8 +82,8 @@ func TestLIDARLiteDriverDistance(t *testing.T) { } distance, err = d.Distance() - gobottest.Assert(t, distance, int(0)) - gobottest.Assert(t, err, ErrNotEnoughBytes) + assert.Equal(t, int(0), distance) + assert.Equal(t, ErrNotEnoughBytes, err) // when read error d, a = initTestLIDARLiteDriverWithStubbedAdaptor() @@ -92,8 +92,8 @@ func TestLIDARLiteDriverDistance(t *testing.T) { } distance, err = d.Distance() - gobottest.Assert(t, distance, int(0)) - gobottest.Assert(t, err, errors.New("read error")) + assert.Equal(t, int(0), distance) + assert.ErrorContains(t, err, "read error") } func TestLIDARLiteDriverDistanceError1(t *testing.T) { @@ -103,8 +103,8 @@ func TestLIDARLiteDriverDistanceError1(t *testing.T) { } distance, err := d.Distance() - gobottest.Assert(t, distance, int(0)) - gobottest.Assert(t, err, errors.New("write error")) + assert.Equal(t, int(0), distance) + assert.ErrorContains(t, err, "write error") } func TestLIDARLiteDriverDistanceError2(t *testing.T) { @@ -117,8 +117,8 @@ func TestLIDARLiteDriverDistanceError2(t *testing.T) { } distance, err := d.Distance() - gobottest.Assert(t, distance, int(0)) - gobottest.Assert(t, err, errors.New("write error")) + assert.Equal(t, int(0), distance) + assert.ErrorContains(t, err, "write error") } func TestLIDARLiteDriverDistanceError3(t *testing.T) { @@ -137,6 +137,6 @@ func TestLIDARLiteDriverDistanceError3(t *testing.T) { } distance, err := d.Distance() - gobottest.Assert(t, distance, int(0)) - gobottest.Assert(t, err, errors.New("write error")) + assert.Equal(t, int(0), distance) + assert.ErrorContains(t, err, "write error") } diff --git a/drivers/i2c/mcp23017_driver.go b/drivers/i2c/mcp23017_driver.go index 0746f5766..4b8697859 100644 --- a/drivers/i2c/mcp23017_driver.go +++ b/drivers/i2c/mcp23017_driver.go @@ -192,7 +192,7 @@ func WithMCP23017Intpol(val uint8) func(Config) { } } -// WithMCP23017ForceWrite option modifies the MCP23017Driver forceRefresh option +// WithMCP23017ForceRefresh option modifies the MCP23017Driver forceRefresh option // Setting to true (1) will force refresh operation to register, although there is no change. // Normally this is not needed, so default is off (0). // When there is something flaky, there is a small chance to stabilize by setting this flag to true. @@ -209,7 +209,7 @@ func WithMCP23017ForceRefresh(val uint8) func(Config) { } // WithMCP23017AutoIODirOff option modifies the MCP23017Driver autoIODirOff option -// Set IO direction at each read or write operation ensures the correct direction, which is the the default setting. +// Set IO direction at each read or write operation ensures the correct direction, which is the default setting. // Most hardware is configured statically, so this can avoided by setting the direction using SetPinMode(), // e.g. in the start up sequence. If this way is taken, the automatic set of direction at each call can // be safely deactivated with this flag (set to true, 1). @@ -234,7 +234,7 @@ func (m *MCP23017Driver) SetPinMode(pin uint8, portStr string, val uint8) (err e selectedPort := m.getPort(portStr) // Set IODIR register bit for given pin to an output/input. - if err = m.write(selectedPort.IODIR, uint8(pin), bitState(val)); err != nil { + if err = m.write(selectedPort.IODIR, pin, bitState(val)); err != nil { return } return @@ -271,7 +271,7 @@ func (m *MCP23017Driver) WriteGPIO(pin uint8, portStr string, val uint8) (err er if !m.mcpBehav.autoIODirOff { // Set IODIR register bit for given pin to an output by clearing bit. // can't call SetPinMode() because mutex will cause deadlock - if err = m.write(selectedPort.IODIR, uint8(pin), clear); err != nil { + if err = m.write(selectedPort.IODIR, pin, clear); err != nil { return err } } @@ -292,7 +292,7 @@ func (m *MCP23017Driver) ReadGPIO(pin uint8, portStr string) (val uint8, err err if !m.mcpBehav.autoIODirOff { // Set IODIR register bit for given pin to an input by set bit. // can't call SetPinMode() because mutex will cause deadlock - if err = m.write(selectedPort.IODIR, uint8(pin), set); err != nil { + if err = m.write(selectedPort.IODIR, pin, set); err != nil { return 0, err } } @@ -300,7 +300,7 @@ func (m *MCP23017Driver) ReadGPIO(pin uint8, portStr string) (val uint8, err err if err != nil { return val, err } - val = 1 << uint8(pin) & val + val = 1 << pin & val if val > 1 { val = 1 } diff --git a/drivers/i2c/mcp23017_driver_test.go b/drivers/i2c/mcp23017_driver_test.go index a682c0caf..f05139c6a 100644 --- a/drivers/i2c/mcp23017_driver_test.go +++ b/drivers/i2c/mcp23017_driver_test.go @@ -5,8 +5,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -31,7 +31,7 @@ func initTestMCP23017(b uint8) (driver *MCP23017Driver) { return d } -func initTestMCP23017WithStubbedAdaptor(b uint8) (*MCP23017Driver, *i2cTestAdaptor) { +func initTestMCP23017WithStubbedAdaptor(b uint8) (*MCP23017Driver, *i2cTestAdaptor) { //nolint:unparam // keep for tests // create the driver, ready to use for tests a := newI2cTestAdaptor() d := NewMCP23017Driver(a, WithMCP23017Bank(b)) @@ -45,56 +45,56 @@ func TestNewMCP23017Driver(t *testing.T) { if !ok { t.Errorf("NewMCP23017Driver() should have returned a *MCP23017Driver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "MCP23017"), true) - gobottest.Assert(t, d.defaultAddress, 0x20) - gobottest.Refute(t, d.mcpConf, nil) - gobottest.Refute(t, d.mcpBehav, nil) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "MCP23017")) + assert.Equal(t, 0x20, d.defaultAddress) + assert.NotNil(t, d.mcpConf) + assert.NotNil(t, d.mcpBehav) } func TestWithMCP23017Bank(t *testing.T) { b := NewMCP23017Driver(newI2cTestAdaptor(), WithMCP23017Bank(1)) - gobottest.Assert(t, b.mcpConf.bank, uint8(1)) + assert.Equal(t, uint8(1), b.mcpConf.bank) } func TestWithMCP23017Mirror(t *testing.T) { b := NewMCP23017Driver(newI2cTestAdaptor(), WithMCP23017Mirror(1)) - gobottest.Assert(t, b.mcpConf.mirror, uint8(1)) + assert.Equal(t, uint8(1), b.mcpConf.mirror) } func TestWithMCP23017Seqop(t *testing.T) { b := NewMCP23017Driver(newI2cTestAdaptor(), WithMCP23017Seqop(1)) - gobottest.Assert(t, b.mcpConf.seqop, uint8(1)) + assert.Equal(t, uint8(1), b.mcpConf.seqop) } func TestWithMCP23017Disslw(t *testing.T) { b := NewMCP23017Driver(newI2cTestAdaptor(), WithMCP23017Disslw(1)) - gobottest.Assert(t, b.mcpConf.disslw, uint8(1)) + assert.Equal(t, uint8(1), b.mcpConf.disslw) } func TestWithMCP23017Haen(t *testing.T) { b := NewMCP23017Driver(newI2cTestAdaptor(), WithMCP23017Haen(1)) - gobottest.Assert(t, b.mcpConf.haen, uint8(1)) + assert.Equal(t, uint8(1), b.mcpConf.haen) } func TestWithMCP23017Odr(t *testing.T) { b := NewMCP23017Driver(newI2cTestAdaptor(), WithMCP23017Odr(1)) - gobottest.Assert(t, b.mcpConf.odr, uint8(1)) + assert.Equal(t, uint8(1), b.mcpConf.odr) } func TestWithMCP23017Intpol(t *testing.T) { b := NewMCP23017Driver(newI2cTestAdaptor(), WithMCP23017Intpol(1)) - gobottest.Assert(t, b.mcpConf.intpol, uint8(1)) + assert.Equal(t, uint8(1), b.mcpConf.intpol) } func TestWithMCP23017ForceRefresh(t *testing.T) { b := NewMCP23017Driver(newI2cTestAdaptor(), WithMCP23017ForceRefresh(1)) - gobottest.Assert(t, b.mcpBehav.forceRefresh, true) + assert.True(t, b.mcpBehav.forceRefresh) } func TestWithMCP23017AutoIODirOff(t *testing.T) { b := NewMCP23017Driver(newI2cTestAdaptor(), WithMCP23017AutoIODirOff(1)) - gobottest.Assert(t, b.mcpBehav.autoIODirOff, true) + assert.True(t, b.mcpBehav.autoIODirOff) } func TestMCP23017CommandsWriteGPIO(t *testing.T) { @@ -103,7 +103,7 @@ func TestMCP23017CommandsWriteGPIO(t *testing.T) { // act result := d.Command("WriteGPIO")(pinValPort) // assert - gobottest.Assert(t, result.(map[string]interface{})["err"], nil) + assert.Nil(t, result.(map[string]interface{})["err"]) } func TestMCP23017CommandsReadGPIO(t *testing.T) { @@ -112,7 +112,7 @@ func TestMCP23017CommandsReadGPIO(t *testing.T) { // act result := d.Command("ReadGPIO")(pinPort) // assert - gobottest.Assert(t, result.(map[string]interface{})["err"], nil) + assert.Nil(t, result.(map[string]interface{})["err"]) } func TestMCP23017WriteGPIO(t *testing.T) { @@ -147,15 +147,15 @@ func TestMCP23017WriteGPIO(t *testing.T) { // act err := d.WriteGPIO(testPin, testPort, uint8(bitState)) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 6) - gobottest.Assert(t, a.written[0], wantReg1) - gobottest.Assert(t, a.written[1], wantReg1) - gobottest.Assert(t, a.written[2], wantReg1Val) - gobottest.Assert(t, a.written[3], wantReg2) - gobottest.Assert(t, a.written[4], wantReg2) - gobottest.Assert(t, a.written[5], wantReg2Val) - gobottest.Assert(t, numCallsRead, 2) + assert.NoError(t, err) + assert.Equal(t, 6, len(a.written)) + assert.Equal(t, wantReg1, a.written[0]) + assert.Equal(t, wantReg1, a.written[1]) + assert.Equal(t, wantReg1Val, a.written[2]) + assert.Equal(t, wantReg2, a.written[3]) + assert.Equal(t, wantReg2, a.written[4]) + assert.Equal(t, wantReg2Val, a.written[5]) + assert.Equal(t, 2, numCallsRead) } } @@ -186,11 +186,11 @@ func TestMCP23017WriteGPIONoRefresh(t *testing.T) { // act err := d.WriteGPIO(testPin, testPort, uint8(bitState)) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 2) - gobottest.Assert(t, a.written[0], wantReg1) - gobottest.Assert(t, a.written[1], wantReg2) - gobottest.Assert(t, numCallsRead, 2) + assert.NoError(t, err) + assert.Equal(t, 2, len(a.written)) + assert.Equal(t, wantReg1, a.written[0]) + assert.Equal(t, wantReg2, a.written[1]) + assert.Equal(t, 2, numCallsRead) } } @@ -223,12 +223,12 @@ func TestMCP23017WriteGPIONoAutoDir(t *testing.T) { // act err := d.WriteGPIO(testPin, testPort, uint8(bitState)) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 3) - gobottest.Assert(t, a.written[0], wantReg) - gobottest.Assert(t, a.written[1], wantReg) - gobottest.Assert(t, a.written[2], wantRegVal) - gobottest.Assert(t, numCallsRead, 1) + assert.NoError(t, err) + assert.Equal(t, 3, len(a.written)) + assert.Equal(t, wantReg, a.written[0]) + assert.Equal(t, wantReg, a.written[1]) + assert.Equal(t, wantRegVal, a.written[2]) + assert.Equal(t, 1, numCallsRead) } } @@ -241,7 +241,7 @@ func TestMCP23017CommandsWriteGPIOErrIODIR(t *testing.T) { // act err := d.WriteGPIO(7, "A", 0) // assert - gobottest.Assert(t, err, errors.New("MCP write-read: MCP write-ReadByteData(reg=0): write error")) + assert.ErrorContains(t, err, "MCP write-read: MCP write-ReadByteData(reg=0): write error") } func TestMCP23017CommandsWriteGPIOErrOLAT(t *testing.T) { @@ -258,7 +258,7 @@ func TestMCP23017CommandsWriteGPIOErrOLAT(t *testing.T) { // act err := d.WriteGPIO(7, "A", 0) // assert - gobottest.Assert(t, err, errors.New("MCP write-read: MCP write-ReadByteData(reg=20): write error")) + assert.ErrorContains(t, err, "MCP write-read: MCP write-ReadByteData(reg=20): write error") } func TestMCP23017ReadGPIO(t *testing.T) { @@ -290,14 +290,14 @@ func TestMCP23017ReadGPIO(t *testing.T) { // act val, err := d.ReadGPIO(testPin, testPort) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, numCallsRead, 2) - gobottest.Assert(t, len(a.written), 4) - gobottest.Assert(t, a.written[0], wantReg1) - gobottest.Assert(t, a.written[1], wantReg1) - gobottest.Assert(t, a.written[2], wantReg1Val) - gobottest.Assert(t, a.written[3], wantReg2) - gobottest.Assert(t, val, uint8(bitState)) + assert.NoError(t, err) + assert.Equal(t, 2, numCallsRead) + assert.Equal(t, 4, len(a.written)) + assert.Equal(t, wantReg1, a.written[0]) + assert.Equal(t, wantReg1, a.written[1]) + assert.Equal(t, wantReg1Val, a.written[2]) + assert.Equal(t, wantReg2, a.written[3]) + assert.Equal(t, uint8(bitState), val) } } @@ -328,12 +328,12 @@ func TestMCP23017ReadGPIONoRefresh(t *testing.T) { // act val, err := d.ReadGPIO(testPin, testPort) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, numCallsRead, 2) - gobottest.Assert(t, len(a.written), 2) - gobottest.Assert(t, a.written[0], wantReg1) - gobottest.Assert(t, a.written[1], wantReg2) - gobottest.Assert(t, val, uint8(bitState)) + assert.NoError(t, err) + assert.Equal(t, 2, numCallsRead) + assert.Equal(t, 2, len(a.written)) + assert.Equal(t, wantReg1, a.written[0]) + assert.Equal(t, wantReg2, a.written[1]) + assert.Equal(t, uint8(bitState), val) } } @@ -363,11 +363,11 @@ func TestMCP23017ReadGPIONoAutoDir(t *testing.T) { // act val, err := d.ReadGPIO(testPin, testPort) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, numCallsRead, 1) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], wantReg2) - gobottest.Assert(t, val, uint8(bitState)) + assert.NoError(t, err) + assert.Equal(t, 1, numCallsRead) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, wantReg2, a.written[0]) + assert.Equal(t, uint8(bitState), val) } } @@ -381,7 +381,7 @@ func TestMCP23017ReadGPIOErr(t *testing.T) { // act _, err := d.ReadGPIO(7, "A") // assert - gobottest.Assert(t, err, errors.New("MCP write-read: MCP write-ReadByteData(reg=0): read error")) + assert.ErrorContains(t, err, "MCP write-read: MCP write-ReadByteData(reg=0): read error") } func TestMCP23017SetPinMode(t *testing.T) { @@ -413,12 +413,12 @@ func TestMCP23017SetPinMode(t *testing.T) { // act err := d.SetPinMode(testPin, testPort, uint8(bitState)) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 3) - gobottest.Assert(t, a.written[0], wantReg) - gobottest.Assert(t, a.written[1], wantReg) - gobottest.Assert(t, a.written[2], wantRegVal) - gobottest.Assert(t, numCallsRead, 1) + assert.NoError(t, err) + assert.Equal(t, 3, len(a.written)) + assert.Equal(t, wantReg, a.written[0]) + assert.Equal(t, wantReg, a.written[1]) + assert.Equal(t, wantRegVal, a.written[2]) + assert.Equal(t, 1, numCallsRead) } } @@ -431,7 +431,7 @@ func TestMCP23017SetPinModeErr(t *testing.T) { // act err := d.SetPinMode(7, "A", 0) // assert - gobottest.Assert(t, err, errors.New("MCP write-read: MCP write-ReadByteData(reg=0): write error")) + assert.ErrorContains(t, err, "MCP write-read: MCP write-ReadByteData(reg=0): write error") } func TestMCP23017SetPullUp(t *testing.T) { @@ -463,12 +463,12 @@ func TestMCP23017SetPullUp(t *testing.T) { // act err := d.SetPullUp(testPin, testPort, uint8(bitState)) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 3) - gobottest.Assert(t, a.written[0], wantReg) - gobottest.Assert(t, a.written[1], wantReg) - gobottest.Assert(t, a.written[2], wantSetVal) - gobottest.Assert(t, numCallsRead, 1) + assert.NoError(t, err) + assert.Equal(t, 3, len(a.written)) + assert.Equal(t, wantReg, a.written[0]) + assert.Equal(t, wantReg, a.written[1]) + assert.Equal(t, wantSetVal, a.written[2]) + assert.Equal(t, 1, numCallsRead) } } @@ -481,7 +481,7 @@ func TestMCP23017SetPullUpErr(t *testing.T) { // act err := d.SetPullUp(7, "A", 0) // assert - gobottest.Assert(t, err, errors.New("MCP write-read: MCP write-ReadByteData(reg=12): write error")) + assert.ErrorContains(t, err, "MCP write-read: MCP write-ReadByteData(reg=12): write error") } func TestMCP23017SetGPIOPolarity(t *testing.T) { @@ -513,12 +513,12 @@ func TestMCP23017SetGPIOPolarity(t *testing.T) { // act err := d.SetGPIOPolarity(testPin, testPort, uint8(bitState)) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 3) - gobottest.Assert(t, a.written[0], wantReg) - gobottest.Assert(t, a.written[1], wantReg) - gobottest.Assert(t, a.written[2], wantSetVal) - gobottest.Assert(t, numCallsRead, 1) + assert.NoError(t, err) + assert.Equal(t, 3, len(a.written)) + assert.Equal(t, wantReg, a.written[0]) + assert.Equal(t, wantReg, a.written[1]) + assert.Equal(t, wantSetVal, a.written[2]) + assert.Equal(t, 1, numCallsRead) } } @@ -531,7 +531,7 @@ func TestMCP23017SetGPIOPolarityErr(t *testing.T) { // act err := d.SetGPIOPolarity(7, "A", 0) // assert - gobottest.Assert(t, err, errors.New("MCP write-read: MCP write-ReadByteData(reg=2): write error")) + assert.ErrorContains(t, err, "MCP write-read: MCP write-ReadByteData(reg=2): write error") } func TestMCP23017_write(t *testing.T) { @@ -539,13 +539,13 @@ func TestMCP23017_write(t *testing.T) { d, _ := initTestMCP23017WithStubbedAdaptor(0) port := d.getPort("A") err := d.write(port.IODIR, uint8(7), 0) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) // set bit d, _ = initTestMCP23017WithStubbedAdaptor(0) port = d.getPort("B") err = d.write(port.IODIR, uint8(7), 1) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) // write error d, a := initTestMCP23017WithStubbedAdaptor(0) @@ -553,7 +553,7 @@ func TestMCP23017_write(t *testing.T) { return 0, errors.New("write error") } err = d.write(port.IODIR, uint8(7), 0) - gobottest.Assert(t, err, errors.New("MCP write-read: MCP write-ReadByteData(reg=1): write error")) + assert.ErrorContains(t, err, "MCP write-read: MCP write-ReadByteData(reg=1): write error") // read error d, a = initTestMCP23017WithStubbedAdaptor(0) @@ -561,12 +561,12 @@ func TestMCP23017_write(t *testing.T) { return len(b), errors.New("read error") } err = d.write(port.IODIR, uint8(7), 0) - gobottest.Assert(t, err, errors.New("MCP write-read: MCP write-ReadByteData(reg=1): read error")) + assert.ErrorContains(t, err, "MCP write-read: MCP write-ReadByteData(reg=1): read error") a.i2cReadImpl = func(b []byte) (int, error) { return len(b), nil } err = d.write(port.IODIR, uint8(7), 1) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) } func TestMCP23017_read(t *testing.T) { @@ -578,7 +578,7 @@ func TestMCP23017_read(t *testing.T) { return 1, nil } val, _ := d.read(port.IODIR) - gobottest.Assert(t, val, uint8(255)) + assert.Equal(t, uint8(255), val) // read error d, a = initTestMCP23017WithStubbedAdaptor(0) @@ -587,8 +587,8 @@ func TestMCP23017_read(t *testing.T) { } val, err := d.read(port.IODIR) - gobottest.Assert(t, val, uint8(0)) - gobottest.Assert(t, err, errors.New("MCP write-ReadByteData(reg=0): read error")) + assert.Equal(t, uint8(0), val) + assert.ErrorContains(t, err, "MCP write-ReadByteData(reg=0): read error") // read d, a = initTestMCP23017WithStubbedAdaptor(0) @@ -598,7 +598,7 @@ func TestMCP23017_read(t *testing.T) { return 1, nil } val, _ = d.read(port.IODIR) - gobottest.Assert(t, val, uint8(255)) + assert.Equal(t, uint8(255), val) } func TestMCP23017_getPort(t *testing.T) { @@ -606,23 +606,23 @@ func TestMCP23017_getPort(t *testing.T) { d := initTestMCP23017(0) expectedPort := mcp23017GetBank(0).portA actualPort := d.getPort("A") - gobottest.Assert(t, expectedPort, actualPort) + assert.Equal(t, actualPort, expectedPort) // port B d = initTestMCP23017(0) expectedPort = mcp23017GetBank(0).portB actualPort = d.getPort("B") - gobottest.Assert(t, expectedPort, actualPort) + assert.Equal(t, actualPort, expectedPort) // default d = initTestMCP23017(0) expectedPort = mcp23017GetBank(0).portA actualPort = d.getPort("") - gobottest.Assert(t, expectedPort, actualPort) + assert.Equal(t, actualPort, expectedPort) // port A bank 1 d = initTestMCP23017(1) expectedPort = mcp23017GetBank(1).portA actualPort = d.getPort("") - gobottest.Assert(t, expectedPort, actualPort) + assert.Equal(t, actualPort, expectedPort) } diff --git a/drivers/i2c/mma7660_driver.go b/drivers/i2c/mma7660_driver.go index 007cc8b97..8e9f5acd5 100644 --- a/drivers/i2c/mma7660_driver.go +++ b/drivers/i2c/mma7660_driver.go @@ -32,12 +32,13 @@ type MMA7660Driver struct { // NewMMA7660Driver creates a new driver with specified i2c interface // Params: -// c Connector - the Adaptor to use with this Driver +// +// c Connector - the Adaptor to use with this Driver // // Optional params: -// i2c.WithBus(int): bus to use with this driver -// i2c.WithAddress(int): address to use with this driver // +// i2c.WithBus(int): bus to use with this driver +// i2c.WithAddress(int): address to use with this driver func NewMMA7660Driver(c Connector, options ...func(Config)) *MMA7660Driver { d := &MMA7660Driver{ Driver: NewDriver(c, "MMA7660", mma7660DefaultAddress), diff --git a/drivers/i2c/mma7660_driver_test.go b/drivers/i2c/mma7660_driver_test.go index d44d0fa87..9f6e4b537 100644 --- a/drivers/i2c/mma7660_driver_test.go +++ b/drivers/i2c/mma7660_driver_test.go @@ -6,8 +6,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -29,43 +29,43 @@ func TestNewMMA7660Driver(t *testing.T) { if !ok { t.Errorf("NewMMA7660Driver() should have returned a *MMA7660Driver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "MMA7660"), true) - gobottest.Assert(t, d.defaultAddress, 0x4c) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "MMA7660")) + assert.Equal(t, 0x4c, d.defaultAddress) } func TestMMA7660Options(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option and // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". d := NewMMA7660Driver(newI2cTestAdaptor(), WithBus(2)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) + assert.Equal(t, 2, d.GetBusOrDefault(1)) } func TestMMA7660Start(t *testing.T) { d := NewMMA7660Driver(newI2cTestAdaptor()) - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestMMA7660Halt(t *testing.T) { d, _ := initTestMMA7660DriverWithStubbedAdaptor() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestMMA7660Acceleration(t *testing.T) { d, _ := initTestMMA7660DriverWithStubbedAdaptor() x, y, z := d.Acceleration(21.0, 21.0, 21.0) - gobottest.Assert(t, x, 1.0) - gobottest.Assert(t, y, 1.0) - gobottest.Assert(t, z, 1.0) + assert.Equal(t, 1.0, x) + assert.Equal(t, 1.0, y) + assert.Equal(t, 1.0, z) } func TestMMA7660NullXYZ(t *testing.T) { d, _ := initTestMMA7660DriverWithStubbedAdaptor() x, y, z, _ := d.XYZ() - gobottest.Assert(t, x, 0.0) - gobottest.Assert(t, y, 0.0) - gobottest.Assert(t, z, 0.0) + assert.Equal(t, 0.0, x) + assert.Equal(t, 0.0, y) + assert.Equal(t, 0.0, z) } func TestMMA7660XYZ(t *testing.T) { @@ -78,9 +78,9 @@ func TestMMA7660XYZ(t *testing.T) { } x, y, z, _ := d.XYZ() - gobottest.Assert(t, x, 17.0) - gobottest.Assert(t, y, 18.0) - gobottest.Assert(t, z, 19.0) + assert.Equal(t, 17.0, x) + assert.Equal(t, 18.0, y) + assert.Equal(t, 19.0, z) } func TestMMA7660XYZError(t *testing.T) { @@ -90,7 +90,7 @@ func TestMMA7660XYZError(t *testing.T) { } _, _, _, err := d.XYZ() - gobottest.Assert(t, err, errors.New("read error")) + assert.ErrorContains(t, err, "read error") } func TestMMA7660XYZNotReady(t *testing.T) { @@ -103,5 +103,5 @@ func TestMMA7660XYZNotReady(t *testing.T) { } _, _, _, err := d.XYZ() - gobottest.Assert(t, err, ErrNotReady) + assert.Equal(t, ErrNotReady, err) } diff --git a/drivers/i2c/mpl115a2_driver.go b/drivers/i2c/mpl115a2_driver.go index 0791a55ae..cbe32206f 100644 --- a/drivers/i2c/mpl115a2_driver.go +++ b/drivers/i2c/mpl115a2_driver.go @@ -1,11 +1,11 @@ package i2c import ( - "gobot.io/x/gobot/v2" - "bytes" "encoding/binary" "time" + + "gobot.io/x/gobot/v2" ) const mpl115a2DefaultAddress = 0x60 diff --git a/drivers/i2c/mpl115a2_driver_test.go b/drivers/i2c/mpl115a2_driver_test.go index 6891e9e47..1b885a61d 100644 --- a/drivers/i2c/mpl115a2_driver_test.go +++ b/drivers/i2c/mpl115a2_driver_test.go @@ -5,8 +5,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -24,16 +24,16 @@ func TestNewMPL115A2Driver(t *testing.T) { if !ok { t.Errorf("NewMPL115A2Driver() should have returned a *MPL115A2Driver") } - gobottest.Refute(t, d.Connection(), nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "MPL115A2"), true) - gobottest.Assert(t, d.defaultAddress, 0x60) + assert.NotNil(t, d.Connection()) + assert.True(t, strings.HasPrefix(d.Name(), "MPL115A2")) + assert.Equal(t, 0x60, d.defaultAddress) } func TestMPL115A2Options(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option and // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". d := NewMPL115A2Driver(newI2cTestAdaptor(), WithBus(2)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) + assert.Equal(t, 2, d.GetBusOrDefault(1)) } func TestMPL115A2ReadData(t *testing.T) { @@ -78,18 +78,18 @@ func TestMPL115A2ReadData(t *testing.T) { press, errP := d.Pressure() temp, errT := d.Temperature() // assert - gobottest.Assert(t, errP, nil) - gobottest.Assert(t, errT, nil) - gobottest.Assert(t, readCallCounter, 2) - gobottest.Assert(t, len(a.written), 6) - gobottest.Assert(t, a.written[0], uint8(0x12)) - gobottest.Assert(t, a.written[1], uint8(0x00)) - gobottest.Assert(t, a.written[2], uint8(0x00)) - gobottest.Assert(t, a.written[3], uint8(0x12)) - gobottest.Assert(t, a.written[4], uint8(0x00)) - gobottest.Assert(t, a.written[5], uint8(0x00)) - gobottest.Assert(t, press, float32(96.585915)) - gobottest.Assert(t, temp, float32(23.317757)) + assert.NoError(t, errP) + assert.NoError(t, errT) + assert.Equal(t, 2, readCallCounter) + assert.Equal(t, 6, len(a.written)) + assert.Equal(t, uint8(0x12), a.written[0]) + assert.Equal(t, uint8(0x00), a.written[1]) + assert.Equal(t, uint8(0x00), a.written[2]) + assert.Equal(t, uint8(0x12), a.written[3]) + assert.Equal(t, uint8(0x00), a.written[4]) + assert.Equal(t, uint8(0x00), a.written[5]) + assert.Equal(t, float32(96.585915), press) + assert.Equal(t, float32(23.317757), temp) } func TestMPL115A2ReadDataError(t *testing.T) { @@ -101,7 +101,7 @@ func TestMPL115A2ReadDataError(t *testing.T) { } _, err := d.Pressure() - gobottest.Assert(t, err, errors.New("write error")) + assert.ErrorContains(t, err, "write error") } func TestMPL115A2_initialization(t *testing.T) { @@ -124,12 +124,12 @@ func TestMPL115A2_initialization(t *testing.T) { // act, assert - initialization() must be called on Start() err := d.Start() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, readCallCounter, 1) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], uint8(0x04)) - gobottest.Assert(t, d.a0, float32(2009.75)) - gobottest.Assert(t, d.b1, float32(-2.3758545)) - gobottest.Assert(t, d.b2, float32(-0.9204712)) - gobottest.Assert(t, d.c12, float32(0.0007901192)) + assert.NoError(t, err) + assert.Equal(t, 1, readCallCounter) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, uint8(0x04), a.written[0]) + assert.Equal(t, float32(2009.75), d.a0) + assert.Equal(t, float32(-2.3758545), d.b1) + assert.Equal(t, float32(-0.9204712), d.b2) + assert.Equal(t, float32(0.0007901192), d.c12) } diff --git a/drivers/i2c/mpu6050_driver.go b/drivers/i2c/mpu6050_driver.go index 38b294945..778e9a5c0 100644 --- a/drivers/i2c/mpu6050_driver.go +++ b/drivers/i2c/mpu6050_driver.go @@ -14,11 +14,13 @@ const ( mpu6050EarthStandardGravity = 9.80665 // [m/s²] standard gravity (pole: 9.834, equator: 9.764) ) -type MPU6050DlpfConfig uint8 -type MPU6050FrameSyncConfig uint8 -type MPU6050GyroFsConfig uint8 -type MPU6050AccelFsConfig uint8 -type MPU6050Pwr1ClockConfig uint8 +type ( + MPU6050DlpfConfig uint8 + MPU6050FrameSyncConfig uint8 + MPU6050GyroFsConfig uint8 + MPU6050AccelFsConfig uint8 + MPU6050Pwr1ClockConfig uint8 +) const ( mpu6050Reg_GeneralConfig = 0x1A // external frame synchronization and digital low pass filter diff --git a/drivers/i2c/mpu6050_driver_test.go b/drivers/i2c/mpu6050_driver_test.go index ac9a3ec9a..4281dce64 100644 --- a/drivers/i2c/mpu6050_driver_test.go +++ b/drivers/i2c/mpu6050_driver_test.go @@ -5,8 +5,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -28,48 +28,48 @@ func TestNewMPU6050Driver(t *testing.T) { if !ok { t.Errorf("NewMPU6050Driver() should have returned a *MPU6050Driver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.name, "MPU6050"), true) - gobottest.Assert(t, d.defaultAddress, 0x68) - gobottest.Assert(t, d.dlpf, MPU6050DlpfConfig(0x00)) - gobottest.Assert(t, d.frameSync, MPU6050FrameSyncConfig(0x00)) - gobottest.Assert(t, d.accelFs, MPU6050AccelFsConfig(0x00)) - gobottest.Assert(t, d.gyroFs, MPU6050GyroFsConfig(0x00)) - gobottest.Assert(t, d.clock, MPU6050Pwr1ClockConfig(0x01)) - gobottest.Assert(t, d.gravity, 9.80665) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.name, "MPU6050")) + assert.Equal(t, 0x68, d.defaultAddress) + assert.Equal(t, MPU6050DlpfConfig(0x00), d.dlpf) + assert.Equal(t, MPU6050FrameSyncConfig(0x00), d.frameSync) + assert.Equal(t, MPU6050AccelFsConfig(0x00), d.accelFs) + assert.Equal(t, MPU6050GyroFsConfig(0x00), d.gyroFs) + assert.Equal(t, MPU6050Pwr1ClockConfig(0x01), d.clock) + assert.Equal(t, 9.80665, d.gravity) } func TestMPU6050Options(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option and // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". d := NewMPU6050Driver(newI2cTestAdaptor(), WithBus(2), WithMPU6050DigitalFilter(0x06)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) - gobottest.Assert(t, d.dlpf, MPU6050DlpfConfig(0x06)) + assert.Equal(t, 2, d.GetBusOrDefault(1)) + assert.Equal(t, MPU6050DlpfConfig(0x06), d.dlpf) } func TestWithMPU6050FrameSync(t *testing.T) { d := NewMPU6050Driver(newI2cTestAdaptor(), WithMPU6050FrameSync(0x07)) - gobottest.Assert(t, d.frameSync, MPU6050FrameSyncConfig(0x07)) + assert.Equal(t, MPU6050FrameSyncConfig(0x07), d.frameSync) } func TestWithMPU6050AccelFullScaleRange(t *testing.T) { d := NewMPU6050Driver(newI2cTestAdaptor(), WithMPU6050AccelFullScaleRange(0x02)) - gobottest.Assert(t, d.accelFs, MPU6050AccelFsConfig(0x02)) + assert.Equal(t, MPU6050AccelFsConfig(0x02), d.accelFs) } func TestWithMPU6050GyroFullScaleRange(t *testing.T) { d := NewMPU6050Driver(newI2cTestAdaptor(), WithMPU6050GyroFullScaleRange(0x03)) - gobottest.Assert(t, d.gyroFs, MPU6050GyroFsConfig(0x03)) + assert.Equal(t, MPU6050GyroFsConfig(0x03), d.gyroFs) } func TestWithMPU6050ClockSource(t *testing.T) { d := NewMPU6050Driver(newI2cTestAdaptor(), WithMPU6050ClockSource(0x05)) - gobottest.Assert(t, d.clock, MPU6050Pwr1ClockConfig(0x05)) + assert.Equal(t, MPU6050Pwr1ClockConfig(0x05), d.clock) } func TestWithMPU6050Gravity(t *testing.T) { d := NewMPU6050Driver(newI2cTestAdaptor(), WithMPU6050Gravity(1.0)) - gobottest.Assert(t, d.gravity, 1.0) + assert.Equal(t, 1.0, d.gravity) } func TestMPU6050GetData(t *testing.T) { @@ -111,9 +111,9 @@ func TestMPU6050GetData(t *testing.T) { // act _ = d.GetData() // assert - gobottest.Assert(t, d.Accelerometer, wantAccel) - gobottest.Assert(t, d.Gyroscope, wantGyro) - gobottest.Assert(t, d.Temperature, wantTemp) + assert.Equal(t, wantAccel, d.Accelerometer) + assert.Equal(t, wantGyro, d.Gyroscope) + assert.Equal(t, wantTemp, d.Temperature) } func TestMPU6050GetDataReadError(t *testing.T) { @@ -124,7 +124,7 @@ func TestMPU6050GetDataReadError(t *testing.T) { return 0, errors.New("read error") } - gobottest.Assert(t, d.GetData(), errors.New("read error")) + assert.ErrorContains(t, d.GetData(), "read error") } func TestMPU6050GetDataWriteError(t *testing.T) { @@ -135,7 +135,7 @@ func TestMPU6050GetDataWriteError(t *testing.T) { return 0, errors.New("write error") } - gobottest.Assert(t, d.GetData(), errors.New("write error")) + assert.ErrorContains(t, d.GetData(), "write error") } func TestMPU6050_initialize(t *testing.T) { @@ -172,20 +172,20 @@ func TestMPU6050_initialize(t *testing.T) { // act, assert - initialize() must be called on Start() err := d.Start() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, readCallCounter, 1) - gobottest.Assert(t, len(a.written), 13) - gobottest.Assert(t, a.written[0], uint8(0x6B)) - gobottest.Assert(t, a.written[1], uint8(0x80)) - gobottest.Assert(t, a.written[2], uint8(0x6B)) - gobottest.Assert(t, a.written[3], uint8(0x68)) - gobottest.Assert(t, a.written[4], uint8(0x07)) - gobottest.Assert(t, a.written[5], uint8(0x1A)) - gobottest.Assert(t, a.written[6], uint8(0x00)) - gobottest.Assert(t, a.written[7], uint8(0x1B)) - gobottest.Assert(t, a.written[8], uint8(0x00)) - gobottest.Assert(t, a.written[9], uint8(0x1C)) - gobottest.Assert(t, a.written[10], uint8(0x00)) - gobottest.Assert(t, a.written[11], uint8(0x6B)) - gobottest.Assert(t, a.written[12], uint8(0x01)) + assert.NoError(t, err) + assert.Equal(t, 1, readCallCounter) + assert.Equal(t, 13, len(a.written)) + assert.Equal(t, uint8(0x6B), a.written[0]) + assert.Equal(t, uint8(0x80), a.written[1]) + assert.Equal(t, uint8(0x6B), a.written[2]) + assert.Equal(t, uint8(0x68), a.written[3]) + assert.Equal(t, uint8(0x07), a.written[4]) + assert.Equal(t, uint8(0x1A), a.written[5]) + assert.Equal(t, uint8(0x00), a.written[6]) + assert.Equal(t, uint8(0x1B), a.written[7]) + assert.Equal(t, uint8(0x00), a.written[8]) + assert.Equal(t, uint8(0x1C), a.written[9]) + assert.Equal(t, uint8(0x00), a.written[10]) + assert.Equal(t, uint8(0x6B), a.written[11]) + assert.Equal(t, uint8(0x01), a.written[12]) } diff --git a/drivers/i2c/pca9501_driver.go b/drivers/i2c/pca9501_driver.go index dd38474d4..05677886b 100644 --- a/drivers/i2c/pca9501_driver.go +++ b/drivers/i2c/pca9501_driver.go @@ -16,7 +16,6 @@ const pca9501DefaultAddress = 0x3F // this applies, if all 6 address pins left o // please refer to data sheet: https://www.nxp.com/docs/en/data-sheet/PCA9501.pdf // // PCA9501 is the replacement for PCF8574, so this driver should also work for PCF8574 except EEPROM calls -// type PCA9501Driver struct { connectionMem Connection *Driver @@ -24,12 +23,13 @@ type PCA9501Driver struct { // NewPCA9501Driver creates a new driver with specified i2c interface // Params: -// a Connector - the Adaptor to use with this Driver +// +// a Connector - the Adaptor to use with this Driver // // Optional params: -// i2c.WithBus(int): bus to use with this driver -// i2c.WithAddress(int): address to use with this driver // +// i2c.WithBus(int): bus to use with this driver +// i2c.WithAddress(int): address to use with this driver func NewPCA9501Driver(a Connector, options ...func(Config)) *PCA9501Driver { p := &PCA9501Driver{ Driver: NewDriver(a, "PCA9501", pca9501DefaultAddress, options...), @@ -76,9 +76,9 @@ func (p *PCA9501Driver) WriteGPIO(pin uint8, val uint8) error { return err } // set pin as output by clearing bit - iodirVal := clearBit(iodir, uint8(pin)) + iodirVal := clearBit(iodir, pin) // write CTRL register - err = p.connection.WriteByte(uint8(iodirVal)) + err = p.connection.WriteByte(iodirVal) if err != nil { return err } @@ -90,12 +90,12 @@ func (p *PCA9501Driver) WriteGPIO(pin uint8, val uint8) error { // set or reset the bit in value var nVal uint8 if val == 0 { - nVal = clearBit(cVal, uint8(pin)) + nVal = clearBit(cVal, pin) } else { - nVal = setBit(cVal, uint8(pin)) + nVal = setBit(cVal, pin) } // write new value to port - err = p.connection.WriteByte(uint8(nVal)) + err = p.connection.WriteByte(nVal) if err != nil { return err } @@ -113,9 +113,9 @@ func (p *PCA9501Driver) ReadGPIO(pin uint8) (uint8, error) { return 0, err } // set pin as input by setting bit - iodirVal := setBit(iodir, uint8(pin)) + iodirVal := setBit(iodir, pin) // write CTRL register - err = p.connection.WriteByte(uint8(iodirVal)) + err = p.connection.WriteByte(iodirVal) if err != nil { return 0, err } @@ -124,7 +124,7 @@ func (p *PCA9501Driver) ReadGPIO(pin uint8) (uint8, error) { if err != nil { return val, err } - val = 1 << uint8(pin) & val + val = 1 << pin & val if val > 1 { val = 1 } diff --git a/drivers/i2c/pca9501_driver_test.go b/drivers/i2c/pca9501_driver_test.go index 8446e43eb..284600d91 100644 --- a/drivers/i2c/pca9501_driver_test.go +++ b/drivers/i2c/pca9501_driver_test.go @@ -5,8 +5,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -47,16 +47,16 @@ func TestNewPCA9501Driver(t *testing.T) { if !ok { t.Errorf("NewPCA9501Driver() should have returned a *PCA9501Driver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "PCA9501"), true) - gobottest.Assert(t, d.defaultAddress, 0x3f) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "PCA9501")) + assert.Equal(t, 0x3f, d.defaultAddress) } func TestPCA9501Options(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option and // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". d := NewPCA9501Driver(newI2cTestAdaptor(), WithBus(2)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) + assert.Equal(t, 2, d.GetBusOrDefault(1)) } func TestPCA9501CommandsWriteGPIO(t *testing.T) { @@ -71,7 +71,7 @@ func TestPCA9501CommandsWriteGPIO(t *testing.T) { // act result := d.Command("WriteGPIO")(pinVal) // assert - gobottest.Assert(t, result.(map[string]interface{})["err"], nil) + assert.Nil(t, result.(map[string]interface{})["err"]) } func TestPCA9501CommandsReadGPIO(t *testing.T) { @@ -83,7 +83,7 @@ func TestPCA9501CommandsReadGPIO(t *testing.T) { // act result := d.Command("ReadGPIO")(pin) // assert - gobottest.Assert(t, result.(map[string]interface{})["err"], nil) + assert.Nil(t, result.(map[string]interface{})["err"]) } func TestPCA9501CommandsWriteEEPROM(t *testing.T) { @@ -95,7 +95,7 @@ func TestPCA9501CommandsWriteEEPROM(t *testing.T) { // act result := d.Command("WriteEEPROM")(addressVal) // assert - gobottest.Assert(t, result.(map[string]interface{})["err"], nil) + assert.Nil(t, result.(map[string]interface{})["err"]) } func TestPCA9501CommandsReadEEPROM(t *testing.T) { @@ -110,11 +110,11 @@ func TestPCA9501CommandsReadEEPROM(t *testing.T) { // act result := d.Command("ReadEEPROM")(address) // assert - gobottest.Assert(t, result.(map[string]interface{})["err"], nil) + assert.Nil(t, result.(map[string]interface{})["err"]) } func TestPCA9501WriteGPIO(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { setVal uint8 ioDirAllInput uint8 ioStateAllInput uint8 @@ -160,11 +160,11 @@ func TestPCA9501WriteGPIO(t *testing.T) { // act err := d.WriteGPIO(tc.pin, tc.setVal) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, numCallsRead, 2) - gobottest.Assert(t, len(a.written), 2) - gobottest.Assert(t, a.written[0], tc.wantPin) - gobottest.Assert(t, a.written[1], tc.wantState) + assert.NoError(t, err) + assert.Equal(t, 2, numCallsRead) + assert.Equal(t, 2, len(a.written)) + assert.Equal(t, tc.wantPin, a.written[0]) + assert.Equal(t, tc.wantState, a.written[1]) }) } } @@ -192,9 +192,9 @@ func TestPCA9501WriteGPIOErrorAtWriteDirection(t *testing.T) { // act err := d.WriteGPIO(7, 0) // assert - gobottest.Assert(t, err, wantErr) - gobottest.Assert(t, numCallsRead < 2, true) - gobottest.Assert(t, numCallsWrite, 1) + assert.Equal(t, wantErr, err) + assert.True(t, numCallsRead < 2) + assert.Equal(t, 1, numCallsWrite) } func TestPCA9501WriteGPIOErrorAtWriteValue(t *testing.T) { @@ -218,12 +218,12 @@ func TestPCA9501WriteGPIOErrorAtWriteValue(t *testing.T) { // act err := d.WriteGPIO(7, 0) // assert - gobottest.Assert(t, err, wantErr) - gobottest.Assert(t, numCallsWrite, 2) + assert.Equal(t, wantErr, err) + assert.Equal(t, 2, numCallsWrite) } func TestPCA9501ReadGPIO(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { ctrlState uint8 want uint8 }{ @@ -254,11 +254,11 @@ func TestPCA9501ReadGPIO(t *testing.T) { // act got, err := d.ReadGPIO(pin) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, got, tc.want) - gobottest.Assert(t, numCallsRead, 2) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], wantCtrlState) + assert.NoError(t, err) + assert.Equal(t, tc.want, got) + assert.Equal(t, 2, numCallsRead) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, wantCtrlState, a.written[0]) }) } } @@ -286,9 +286,9 @@ func TestPCA9501ReadGPIOErrorAtReadDirection(t *testing.T) { // act _, err := d.ReadGPIO(1) // assert - gobottest.Assert(t, err, wantErr) - gobottest.Assert(t, numCallsRead, 1) - gobottest.Assert(t, numCallsWrite, 0) + assert.Equal(t, wantErr, err) + assert.Equal(t, 1, numCallsRead) + assert.Equal(t, 0, numCallsWrite) } func TestPCA9501ReadGPIOErrorAtReadValue(t *testing.T) { @@ -314,8 +314,8 @@ func TestPCA9501ReadGPIOErrorAtReadValue(t *testing.T) { // act _, err := d.ReadGPIO(2) // assert - gobottest.Assert(t, err, wantErr) - gobottest.Assert(t, numCallsWrite, 1) + assert.Equal(t, wantErr, err) + assert.Equal(t, 1, numCallsWrite) } func TestPCA9501WriteEEPROM(t *testing.T) { @@ -334,10 +334,10 @@ func TestPCA9501WriteEEPROM(t *testing.T) { // act err := d.WriteEEPROM(addressEEPROM, want) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, numCallsWrite, 1) - gobottest.Assert(t, a.written[0], addressEEPROM) - gobottest.Assert(t, a.written[1], want) + assert.NoError(t, err) + assert.Equal(t, 1, numCallsWrite) + assert.Equal(t, addressEEPROM, a.written[0]) + assert.Equal(t, want, a.written[1]) } func TestPCA9501ReadEEPROM(t *testing.T) { @@ -363,11 +363,11 @@ func TestPCA9501ReadEEPROM(t *testing.T) { // act val, err := d.ReadEEPROM(addressEEPROM) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, val, want) - gobottest.Assert(t, numCallsWrite, 1) - gobottest.Assert(t, a.written[0], addressEEPROM) - gobottest.Assert(t, numCallsRead, 1) + assert.NoError(t, err) + assert.Equal(t, want, val) + assert.Equal(t, 1, numCallsWrite) + assert.Equal(t, addressEEPROM, a.written[0]) + assert.Equal(t, 1, numCallsRead) } func TestPCA9501ReadEEPROMErrorWhileWriteAddress(t *testing.T) { @@ -387,8 +387,8 @@ func TestPCA9501ReadEEPROMErrorWhileWriteAddress(t *testing.T) { // act _, err := d.ReadEEPROM(15) // assert - gobottest.Assert(t, err, wantErr) - gobottest.Assert(t, numCallsRead, 0) + assert.Equal(t, wantErr, err) + assert.Equal(t, 0, numCallsRead) } func TestPCA9501ReadEEPROMErrorWhileReadValue(t *testing.T) { @@ -408,8 +408,8 @@ func TestPCA9501ReadEEPROMErrorWhileReadValue(t *testing.T) { // act _, err := d.ReadEEPROM(15) // assert - gobottest.Assert(t, numCallsWrite, 1) - gobottest.Assert(t, err, wantErr) + assert.Equal(t, 1, numCallsWrite) + assert.Equal(t, wantErr, err) } func TestPCA9501_initialize(t *testing.T) { @@ -419,6 +419,6 @@ func TestPCA9501_initialize(t *testing.T) { // act err := d.initialize() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, a.address, want) + assert.NoError(t, err) + assert.Equal(t, want, a.address) } diff --git a/drivers/i2c/pca953x_driver.go b/drivers/i2c/pca953x_driver.go index 94151fba0..fd193441a 100644 --- a/drivers/i2c/pca953x_driver.go +++ b/drivers/i2c/pca953x_driver.go @@ -36,10 +36,12 @@ const ( PCA953xModePwm1 PCA953xGPIOMode = 0x03 ) -var errToSmallPeriod = fmt.Errorf("Given Period to small, must be at least 1/152s (~6.58ms) or 152Hz") -var errToBigPeriod = fmt.Errorf("Given Period to high, must be max. 256/152s (~1.68s) or 152/256Hz (~0.6Hz)") -var errToSmallDutyCycle = fmt.Errorf("Given Duty Cycle to small, must be at least 0%%") -var errToBigDutyCycle = fmt.Errorf("Given Duty Cycle to high, must be max. 100%%") +var ( + errToSmallPeriod = fmt.Errorf("Given Period to small, must be at least 1/152s (~6.58ms) or 152Hz") + errToBigPeriod = fmt.Errorf("Given Period to high, must be max. 256/152s (~1.68s) or 152/256Hz (~0.6Hz)") + errToSmallDutyCycle = fmt.Errorf("Given Duty Cycle to small, must be at least 0%%") + errToBigDutyCycle = fmt.Errorf("Given Duty Cycle to high, must be max. 100%%") +) // PCA953xDriver is a Gobot Driver for LED Dimmer PCA9530 (2-bit), PCA9533 (4-bit), PCA9531 (8-bit), PCA9532 (16-bit) // Although this is designed for LED's it can be used as a GPIO (read, write, pwm). @@ -118,7 +120,7 @@ func (d *PCA953xDriver) ReadGPIO(idx uint8) (uint8, error) { if err != nil { return val, err } - val = 1 << uint8(idx) & val + val = 1 << idx & val if val > 1 { val = 1 } @@ -133,7 +135,7 @@ func (d *PCA953xDriver) WritePeriod(idx uint8, valSec float32) error { // period is valid in range ~6.58ms..1.68s val, err := pca953xCalcPsc(valSec) if err != nil && pca953xDebug { - fmt.Println(err, "value shrinked!") + fmt.Println(err, "value limited!") } var regPsc pca953xRegister = pca953xRegPsc0 if idx > 0 { @@ -166,7 +168,7 @@ func (d *PCA953xDriver) WriteFrequency(idx uint8, valHz float32) error { // frequency is valid in range ~0.6..152Hz val, err := pca953xCalcPsc(1 / valHz) if err != nil && pca953xDebug { - fmt.Println(err, "value shrinked!") + fmt.Println(err, "value limited!") } regPsc := pca953xRegPsc0 if idx > 0 { @@ -199,7 +201,7 @@ func (d *PCA953xDriver) WriteDutyCyclePercent(idx uint8, valPercent float32) err val, err := pca953xCalcPwm(valPercent) if err != nil && pca953xDebug { - fmt.Println(err, "value shrinked!") + fmt.Println(err, "value limited!") } regPwm := pca953xRegPwm0 if idx > 0 { diff --git a/drivers/i2c/pca953x_driver_test.go b/drivers/i2c/pca953x_driver_test.go index 0dfd3aa64..8aac72dd0 100644 --- a/drivers/i2c/pca953x_driver_test.go +++ b/drivers/i2c/pca953x_driver_test.go @@ -6,8 +6,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -29,9 +29,9 @@ func TestNewPCA953xDriver(t *testing.T) { if !ok { t.Errorf("NewPCA953xDriver() should have returned a *PCA953xDriver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "PCA953x"), true) - gobottest.Assert(t, d.defaultAddress, 0x63) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "PCA953x")) + assert.Equal(t, 0x63, d.defaultAddress) } func TestPCA953xWriteGPIO(t *testing.T) { @@ -40,7 +40,7 @@ func TestPCA953xWriteGPIO(t *testing.T) { // * read current state of LED select register (write reg, read val) // * modify 2 bits according to given index of GPIO // * write the new state to the LED select register (write reg, write val) - var tests = map[string]struct { + tests := map[string]struct { idx uint8 ls0State uint8 ls1State uint8 @@ -99,8 +99,8 @@ func TestPCA953xWriteGPIO(t *testing.T) { // act err := d.WriteGPIO(tc.idx, tc.val) // assert - gobottest.Assert(t, err, tc.wantErr) - gobottest.Assert(t, a.written, tc.wantWritten) + assert.Equal(t, tc.wantErr, err) + assert.Equal(t, tc.wantWritten, a.written) }) } } @@ -109,7 +109,7 @@ func TestPCA953xReadGPIO(t *testing.T) { // sequence to read: // * read current state of INPUT register (write reg 0x00, read val) // * convert bit position to output value - var tests = map[string]struct { + tests := map[string]struct { idx uint8 want uint8 wantErr error @@ -158,10 +158,10 @@ func TestPCA953xReadGPIO(t *testing.T) { // act got, err := d.ReadGPIO(tc.idx) // assert - gobottest.Assert(t, err, tc.wantErr) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], wantReg) - gobottest.Assert(t, got, tc.want) + assert.Equal(t, tc.wantErr, err) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, wantReg, a.written[0]) + assert.Equal(t, tc.want, got) }) } } @@ -171,7 +171,7 @@ func TestPCA953xWritePeriod(t *testing.T) { // * calculate PSC value (0..255) from given value in seconds, valid values are 0.00658 ... 1.68 [s] // * choose PSC0 (0x01) or PSC1 (0x03) frequency prescaler register by the given index // * write the value to the register (write reg, write val) - var tests = map[string]struct { + tests := map[string]struct { idx uint8 val float32 wantWritten []uint8 @@ -186,7 +186,7 @@ func TestPCA953xWritePeriod(t *testing.T) { val: 0.5, wantWritten: []byte{0x03, 75}, }, - "write_shrinked_noerror": { + "write_limited_noerror": { idx: 0, val: 2, wantWritten: []byte{0x01, 255}, @@ -200,8 +200,8 @@ func TestPCA953xWritePeriod(t *testing.T) { // act err := d.WritePeriod(tc.idx, tc.val) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, a.written, tc.wantWritten) + assert.NoError(t, err) + assert.Equal(t, tc.wantWritten, a.written) }) } } @@ -211,7 +211,7 @@ func TestPCA953xReadPeriod(t *testing.T) { // * choose PSC0 (0x01) or PSC1 (0x03) frequency prescaler register by the given index // * read the value from the register (write reg, write val) // * calculate value in seconds from PSC value - var tests = map[string]struct { + tests := map[string]struct { idx uint8 val uint8 want float32 @@ -250,9 +250,9 @@ func TestPCA953xReadPeriod(t *testing.T) { // act got, err := d.ReadPeriod(tc.idx) // assert - gobottest.Assert(t, err, tc.wantErr) - gobottest.Assert(t, got, tc.want) - gobottest.Assert(t, a.written, tc.wantWritten) + assert.Equal(t, tc.wantErr, err) + assert.Equal(t, tc.want, got) + assert.Equal(t, tc.wantWritten, a.written) }) } } @@ -262,7 +262,7 @@ func TestPCA953xWriteFrequency(t *testing.T) { // * calculate PSC value (0..255) from given value in Hz, valid values are 0.6 ... 152 [Hz] // * choose PSC0 (0x01) or PSC1 (0x03) frequency prescaler register by the given index // * write the value to the register (write reg, write val) - var tests = map[string]struct { + tests := map[string]struct { idx uint8 val float32 wantWritten []uint8 @@ -277,7 +277,7 @@ func TestPCA953xWriteFrequency(t *testing.T) { val: 2, wantWritten: []byte{0x03, 75}, }, - "write_shrinked_noerror": { + "write_limited_noerror": { idx: 0, val: 153, wantWritten: []byte{0x01, 0}, @@ -291,8 +291,8 @@ func TestPCA953xWriteFrequency(t *testing.T) { // act err := d.WriteFrequency(tc.idx, tc.val) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, a.written, tc.wantWritten) + assert.NoError(t, err) + assert.Equal(t, tc.wantWritten, a.written) }) } } @@ -302,7 +302,7 @@ func TestPCA953xReadFrequency(t *testing.T) { // * choose PSC0 (0x01) or PSC1 (0x03) frequency prescaler register by the given index // * read the value from the register (write reg, write val) // * calculate value in Hz from PSC value - var tests = map[string]struct { + tests := map[string]struct { idx uint8 val uint8 want float32 @@ -341,9 +341,9 @@ func TestPCA953xReadFrequency(t *testing.T) { // act got, err := d.ReadFrequency(tc.idx) // assert - gobottest.Assert(t, err, tc.wantErr) - gobottest.Assert(t, got, tc.want) - gobottest.Assert(t, a.written, tc.wantWritten) + assert.Equal(t, tc.wantErr, err) + assert.Equal(t, tc.want, got) + assert.Equal(t, tc.wantWritten, a.written) }) } } @@ -353,7 +353,7 @@ func TestPCA953xWriteDutyCyclePercent(t *testing.T) { // * calculate PWM value (0..255) from given value in percent, valid values are 0 ... 100 [%] // * choose PWM0 (0x02) or PWM1 (0x04) pwm register by the given index // * write the value to the register (write reg, write val) - var tests = map[string]struct { + tests := map[string]struct { idx uint8 val float32 wantWritten []uint8 @@ -368,7 +368,7 @@ func TestPCA953xWriteDutyCyclePercent(t *testing.T) { val: 50, wantWritten: []byte{0x04, 128}, }, - "write_shrinked_noerror": { + "write_limited_noerror": { idx: 1, val: 101, wantWritten: []byte{0x04, 255}, @@ -382,8 +382,8 @@ func TestPCA953xWriteDutyCyclePercent(t *testing.T) { // act err := d.WriteDutyCyclePercent(tc.idx, tc.val) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, a.written, tc.wantWritten) + assert.NoError(t, err) + assert.Equal(t, tc.wantWritten, a.written) }) } } @@ -393,7 +393,7 @@ func TestPCA953xReadDutyCyclePercent(t *testing.T) { // * choose PWM0 (0x02) or PWM1 (0x04) pwm register by the given index // * read the value from the register (write reg, write val) // * calculate value percent from PWM value - var tests = map[string]struct { + tests := map[string]struct { idx uint8 val uint8 want float32 @@ -432,9 +432,9 @@ func TestPCA953xReadDutyCyclePercent(t *testing.T) { // act got, err := d.ReadDutyCyclePercent(tc.idx) // assert - gobottest.Assert(t, err, tc.wantErr) - gobottest.Assert(t, got, tc.want) - gobottest.Assert(t, a.written, tc.wantWritten) + assert.Equal(t, tc.wantErr, err) + assert.Equal(t, tc.want, got) + assert.Equal(t, tc.wantWritten, a.written) }) } } @@ -465,13 +465,13 @@ func TestPCA953x_readRegister(t *testing.T) { // act val, err := d.readRegister(wantRegAddress) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, numCallsRead, 1) - gobottest.Assert(t, numCallsWrite, 1) - gobottest.Assert(t, val, wantRegVal) - gobottest.Assert(t, readByteCount, wantReadByteCount) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], uint8(wantRegAddress)) + assert.NoError(t, err) + assert.Equal(t, 1, numCallsRead) + assert.Equal(t, 1, numCallsWrite) + assert.Equal(t, wantRegVal, val) + assert.Equal(t, wantReadByteCount, readByteCount) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, uint8(wantRegAddress), a.written[0]) } func TestPCA953x_writeRegister(t *testing.T) { @@ -491,12 +491,12 @@ func TestPCA953x_writeRegister(t *testing.T) { // act err := d.writeRegister(wantRegAddress, wantRegVal) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, numCallsWrite, 1) - gobottest.Assert(t, numCallsWrite, 1) - gobottest.Assert(t, len(a.written), wantByteCount) - gobottest.Assert(t, a.written[0], uint8(wantRegAddress)) - gobottest.Assert(t, a.written[1], uint8(wantRegVal)) + assert.NoError(t, err) + assert.Equal(t, 1, numCallsWrite) + assert.Equal(t, 1, numCallsWrite) + assert.Equal(t, wantByteCount, len(a.written)) + assert.Equal(t, uint8(wantRegAddress), a.written[0]) + assert.Equal(t, wantRegVal, a.written[1]) } func TestPCA953x_pca953xCalcPsc(t *testing.T) { @@ -517,8 +517,8 @@ func TestPCA953x_pca953xCalcPsc(t *testing.T) { // act val, err := pca953xCalcPsc(tc.period) // assert - gobottest.Assert(t, err, tc.wantErr) - gobottest.Assert(t, val, tc.want) + assert.Equal(t, tc.wantErr, err) + assert.Equal(t, tc.want, val) }) } } @@ -539,7 +539,7 @@ func TestPCA953x_pca953xCalcPeriod(t *testing.T) { // act val := pca953xCalcPeriod(tc.psc) // assert - gobottest.Assert(t, float32(math.Round(float64(val)*10000)/10000), tc.want) + assert.Equal(t, tc.want, float32(math.Round(float64(val)*10000)/10000)) }) } } @@ -563,8 +563,8 @@ func TestPCA953x_pca953xCalcPwm(t *testing.T) { // act val, err := pca953xCalcPwm(tc.percent) // assert - gobottest.Assert(t, err, tc.wantErr) - gobottest.Assert(t, val, tc.want) + assert.Equal(t, tc.wantErr, err) + assert.Equal(t, tc.want, val) }) } } @@ -585,7 +585,7 @@ func TestPCA953x_pca953xCalcDutyCyclePercent(t *testing.T) { // act val := pca953xCalcDutyCyclePercent(tc.pwm) // assert - gobottest.Assert(t, float32(math.Round(float64(val)*10)/10), tc.want) + assert.Equal(t, tc.want, float32(math.Round(float64(val)*10)/10)) }) } } diff --git a/drivers/i2c/pca9685_driver.go b/drivers/i2c/pca9685_driver.go index 34ea629cf..b8c1eddd2 100644 --- a/drivers/i2c/pca9685_driver.go +++ b/drivers/i2c/pca9685_driver.go @@ -10,26 +10,27 @@ import ( const pca9685DefaultAddress = 0x40 const ( - PCA9685_MODE1 = 0x00 - PCA9685_MODE2 = 0x01 - PCA9685_PRESCALE = 0xFE - PCA9685_SUBADR1 = 0x02 - PCA9685_SUBADR2 = 0x03 - PCA9685_SUBADR3 = 0x04 - PCA9685_LED0_ON_L = 0x06 - PCA9685_LED0_ON_H = 0x07 - PCA9685_LED0_OFF_L = 0x08 - PCA9685_LED0_OFF_H = 0x09 - PCA9685_ALLLED_ON_L = 0xFA - PCA9685_ALLLED_ON_H = 0xFB - PCA9685_ALLLED_OFF_L = 0xFC - PCA9685_ALLLED_OFF_H = 0xFD - - PCA9685_RESTART = 0x80 - PCA9685_SLEEP = 0x10 - PCA9685_ALLCALL = 0x01 - PCA9685_INVRT = 0x10 - PCA9685_OUTDRV = 0x04 + pca9685Mode1Reg = 0x00 + pca9685Mode2Reg = 0x01 + pca9685Subadr1Reg = 0x02 + pca9685Subadr2Reg = 0x03 + pca9685Subadr3Reg = 0x04 + pca9685Led0OnLReg = 0x06 + pca9685Led0OnHReg = 0x07 + pca9685Led0OffLReg = 0x08 + pca9685Led0OffHReg = 0x09 + pca9685AllLedOnLReg = 0xFA + pca9685AllLedOnHReg = 0xFB + pca9685AllLedOffLReg = 0xFC + pca9685AllLedOffHReg = 0xFD + pca9685PrescaleReg = 0xFE + + pca9685Mode1RegRestartBit = 0x80 // bit 7 - 0: restart disabled (default) + pca9685Mode1RegSleepBit = 0x10 // bit 4 - 0: normal, 1: low power (default) + pca9685Mode1RegAllCallBit = 0x01 // bit 0 - 0: no response to all-call, 1: respond to all-call (default) + pca9685Mode2RegInvertBit = 0x10 // bit 4 - 0: outputs not inverted (default), 1: outputs inverted + pca9685Mode2RegOutdrvBit = 0x04 // bit 2 - 0: open-drain, 1: totem-pole (default) + pca9685AllLedOffHRegShutDown = 0x10 // bit 4 - 1: orderly shut down ) // PCA9685Driver is a Gobot Driver for the PCA9685 16-channel 12-bit PWM/Servo controller. @@ -93,19 +94,19 @@ func NewPCA9685Driver(c Connector, options ...func(Config)) *PCA9685Driver { // // Most typically you set "on" to a zero value, and then set "off" to your desired duty. func (p *PCA9685Driver) SetPWM(channel int, on uint16, off uint16) (err error) { - if _, err := p.connection.Write([]byte{byte(PCA9685_LED0_ON_L + 4*channel), byte(on) & 0xFF}); err != nil { + if _, err := p.connection.Write([]byte{byte(pca9685Led0OnLReg + 4*channel), byte(on) & 0xFF}); err != nil { return err } - if _, err := p.connection.Write([]byte{byte(PCA9685_LED0_ON_H + 4*channel), byte(on >> 8)}); err != nil { + if _, err := p.connection.Write([]byte{byte(pca9685Led0OnHReg + 4*channel), byte(on >> 8)}); err != nil { return err } - if _, err := p.connection.Write([]byte{byte(PCA9685_LED0_OFF_L + 4*channel), byte(off) & 0xFF}); err != nil { + if _, err := p.connection.Write([]byte{byte(pca9685Led0OffLReg + 4*channel), byte(off) & 0xFF}); err != nil { return err } - if _, err := p.connection.Write([]byte{byte(PCA9685_LED0_OFF_H + 4*channel), byte(off >> 8)}); err != nil { + if _, err := p.connection.Write([]byte{byte(pca9685Led0OffHReg + 4*channel), byte(off >> 8)}); err != nil { return err } @@ -120,38 +121,38 @@ func (p *PCA9685Driver) SetPWM(channel int, on uint16, off uint16) (err error) { // // Most typically you set "on" to a zero value, and then set "off" to your desired duty. func (p *PCA9685Driver) SetAllPWM(on uint16, off uint16) (err error) { - if _, err := p.connection.Write([]byte{byte(PCA9685_ALLLED_ON_L), byte(on) & 0xFF}); err != nil { + if _, err := p.connection.Write([]byte{byte(pca9685AllLedOnLReg), byte(on) & 0xFF}); err != nil { return err } - if _, err := p.connection.Write([]byte{byte(PCA9685_ALLLED_ON_H), byte(on >> 8)}); err != nil { + if _, err := p.connection.Write([]byte{byte(pca9685AllLedOnHReg), byte(on >> 8)}); err != nil { return err } - if _, err := p.connection.Write([]byte{byte(PCA9685_ALLLED_OFF_L), byte(off) & 0xFF}); err != nil { + if _, err := p.connection.Write([]byte{byte(pca9685AllLedOffLReg), byte(off) & 0xFF}); err != nil { return err } - if _, err := p.connection.Write([]byte{byte(PCA9685_ALLLED_OFF_H), byte(off >> 8)}); err != nil { + if _, err := p.connection.Write([]byte{byte(pca9685AllLedOffHReg), byte(off >> 8)}); err != nil { return err } return } -// SetPWMFreq sets the PWM frequency in Hz +// SetPWMFreq sets the PWM frequency in Hz between 24Hz and 1526Hz, the default is 200Hz. func (p *PCA9685Driver) SetPWMFreq(freq float32) error { - // IC oscillator frequency is 25 MHz + // internal IC oscillator frequency is 25 MHz var prescalevel float32 = 25000000 - // Find frequency of PWM waveform + // find frequency of PWM waveform prescalevel /= 4096 - // Ratio between desired frequency and maximum + // ratio between desired frequency and maximum prescalevel /= freq prescalevel-- - // Round value to nearest whole + // round value to nearest whole prescale := byte(prescalevel + 0.5) - if _, err := p.connection.Write([]byte{byte(PCA9685_MODE1)}); err != nil { + if _, err := p.connection.Write([]byte{byte(pca9685Mode1Reg)}); err != nil { return err } oldmode, err := p.connection.ReadByte() @@ -159,25 +160,27 @@ func (p *PCA9685Driver) SetPWMFreq(freq float32) error { return err } - // Put oscillator in sleep mode, clear bit 7 here to avoid overwriting - // previous setting - newmode := (oldmode & 0x7F) | 0x10 - if _, err := p.connection.Write([]byte{byte(PCA9685_MODE1), byte(newmode)}); err != nil { + // put oscillator in sleep mode, clear the restart bit 7 here to prevent unneeded restart + sleepMode := (oldmode &^ pca9685Mode1RegRestartBit) | pca9685Mode1RegSleepBit + if _, err := p.connection.Write([]byte{byte(pca9685Mode1Reg), sleepMode}); err != nil { return err } - // Write prescaler value - if _, err := p.connection.Write([]byte{byte(PCA9685_PRESCALE), prescale}); err != nil { + // write prescaler value + if _, err := p.connection.Write([]byte{byte(pca9685PrescaleReg), prescale}); err != nil { return err } - // Put back to old settings - if _, err := p.connection.Write([]byte{byte(PCA9685_MODE1), byte(oldmode)}); err != nil { + // put back to old settings, ensure no sleep + noSleepMode := oldmode &^ pca9685Mode1RegSleepBit + if _, err := p.connection.Write([]byte{byte(pca9685Mode1Reg), noSleepMode}); err != nil { return err } + // wait >500us according to data sheet time.Sleep(5 * time.Millisecond) - // Enable response to All Call address, enable auto-increment, clear restart - if _, err := p.connection.Write([]byte{byte(PCA9685_MODE1), byte(oldmode | 0x80)}); err != nil { + // initiate a restart + restartMode := oldmode | pca9685Mode1RegRestartBit + if _, err := p.connection.Write([]byte{byte(pca9685Mode1Reg), restartMode}); err != nil { return err } @@ -208,31 +211,38 @@ func (p *PCA9685Driver) ServoWrite(pin string, val byte) (err error) { return p.SetPWM(i, 0, uint16(v)) } +// initialize the driver according to the data sheet section "7.3.1.1 Restart mode" +// * ensure the sleep bit is unset +// * wait > 500us +// * write a logic 1 to bit 7 (RESTART) of register "MODE1" func (p *PCA9685Driver) initialize() error { if err := p.SetAllPWM(0, 0); err != nil { return err } - if _, err := p.connection.Write([]byte{PCA9685_MODE2, PCA9685_OUTDRV}); err != nil { + // set not inverted (default), outputs change on stop (default), OE reaction to 0 (default), totem-pole (default) + if _, err := p.connection.Write([]byte{pca9685Mode2Reg, pca9685Mode2RegOutdrvBit}); err != nil { return err } - - if _, err := p.connection.Write([]byte{PCA9685_MODE1, PCA9685_ALLCALL}); err != nil { + // reset of sleep bit together with set of no restart (default), internal clock (default), no AI (default), + // no response to sub address 1, 2 or 3 (default), activate response to all-call (default) + if _, err := p.connection.Write([]byte{pca9685Mode1Reg, pca9685Mode1RegAllCallBit}); err != nil { return err } time.Sleep(5 * time.Millisecond) - if _, err := p.connection.Write([]byte{byte(PCA9685_MODE1)}); err != nil { + // initiate the restart + if _, err := p.connection.Write([]byte{byte(pca9685Mode1Reg)}); err != nil { return err } oldmode, err := p.connection.ReadByte() if err != nil { return err } - oldmode = oldmode &^ byte(PCA9685_SLEEP) + oldmode = oldmode | byte(pca9685Mode1RegRestartBit) - if _, err := p.connection.Write([]byte{PCA9685_MODE1, oldmode}); err != nil { + if _, err := p.connection.Write([]byte{pca9685Mode1Reg, oldmode}); err != nil { return err } @@ -242,6 +252,6 @@ func (p *PCA9685Driver) initialize() error { } func (p *PCA9685Driver) shutdown() error { - _, err := p.connection.Write([]byte{PCA9685_ALLLED_OFF_H, 0x10}) + _, err := p.connection.Write([]byte{pca9685AllLedOffHReg, pca9685AllLedOffHRegShutDown}) return err } diff --git a/drivers/i2c/pca9685_driver_test.go b/drivers/i2c/pca9685_driver_test.go index d77484449..b9a3b0730 100644 --- a/drivers/i2c/pca9685_driver_test.go +++ b/drivers/i2c/pca9685_driver_test.go @@ -5,9 +5,9 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" "gobot.io/x/gobot/v2/drivers/gpio" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -15,10 +15,12 @@ import ( var _ gobot.Driver = (*PCA9685Driver)(nil) // and also the PwmWriter and ServoWriter interfaces -var _ gpio.PwmWriter = (*PCA9685Driver)(nil) -var _ gpio.ServoWriter = (*PCA9685Driver)(nil) +var ( + _ gpio.PwmWriter = (*PCA9685Driver)(nil) + _ gpio.ServoWriter = (*PCA9685Driver)(nil) +) -func initTestPCA9685DriverWithStubbedAdaptor() (*PCA9685Driver, *i2cTestAdaptor) { +func initTestPCA9685WithStubbedAdaptor() (*PCA9685Driver, *i2cTestAdaptor) { a := newI2cTestAdaptor() d := NewPCA9685Driver(a) if err := d.Start(); err != nil { @@ -28,126 +30,320 @@ func initTestPCA9685DriverWithStubbedAdaptor() (*PCA9685Driver, *i2cTestAdaptor) } func TestNewPCA9685Driver(t *testing.T) { - var di interface{} = NewPCA9685Driver(newI2cTestAdaptor()) - d, ok := di.(*PCA9685Driver) - if !ok { - t.Errorf("NewPCA9685Driver() should have returned a *PCA9685Driver") - } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "PCA9685"), true) - gobottest.Assert(t, d.defaultAddress, 0x40) + // arrange & act + d := NewPCA9685Driver(newI2cTestAdaptor()) + // assert + assert.IsType(t, &PCA9685Driver{}, d) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "PCA9685")) + assert.Equal(t, 0x40, d.defaultAddress) } func TestPCA9685Options(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option and // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". + // arrange & act d := NewPCA9685Driver(newI2cTestAdaptor(), WithBus(2)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) + // assert + assert.Equal(t, 2, d.GetBusOrDefault(1)) } func TestPCA9685Start(t *testing.T) { + // arrange a := newI2cTestAdaptor() d := NewPCA9685Driver(a) a.i2cReadImpl = func(b []byte) (int, error) { copy(b, []byte{0x01}) return 1, nil } - gobottest.Assert(t, d.Start(), nil) + // act & assert + assert.NoError(t, d.Start()) +} + +func TestPCA9685StartError(t *testing.T) { + // arrange + a := newI2cTestAdaptor() + d := NewPCA9685Driver(a) + a.i2cWriteImpl = func([]byte) (int, error) { + return 0, errors.New("write error") + } + // act & assert + assert.ErrorContains(t, d.Start(), "write error") } func TestPCA9685Halt(t *testing.T) { - d, a := initTestPCA9685DriverWithStubbedAdaptor() - a.i2cReadImpl = func(b []byte) (int, error) { - copy(b, []byte{0x01}) - return 1, nil + // arrange + d, a := initTestPCA9685WithStubbedAdaptor() + a.written = []byte{} // reset writes of former test + // act + err := d.Halt() + // assert + assert.NoError(t, err) + assert.NoError(t, err) + assert.Equal(t, 2, len(a.written)) + assert.Equal(t, []byte{0xFD, 0x10}, a.written) +} + +func TestPCA9685HaltError(t *testing.T) { + // arrange + d, a := initTestPCA9685WithStubbedAdaptor() + a.i2cWriteImpl = func([]byte) (int, error) { + return 0, errors.New("write error") } - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Halt(), nil) + // act & assert + assert.ErrorContains(t, d.Halt(), "write error") } func TestPCA9685SetPWM(t *testing.T) { - d, a := initTestPCA9685DriverWithStubbedAdaptor() - a.i2cReadImpl = func(b []byte) (int, error) { - copy(b, []byte{0x01}) - return 1, nil + // sequence to set PWM for PCA9685: + // * set LEDn ON-time register (n=0: 0x06, 0x07, n=1: 0x0A, 0x0B ... n=14: 0x3E, 0x3F, n=15: 0x42, 0x43) + // * set LEDn OFF-time register (n=0: 0x08, 0x09, n=1: 0x0C, 0x0D ... n=14: 0x40, 0x41, n=15: 0x44, 0x45) + tests := map[string]struct { + pin int + onCounts uint16 + offCounts uint16 + wantLedOnTimeOffTimeSet []uint8 + }{ + "example1_datasheet": { + pin: 0, + onCounts: 409, + offCounts: 1228, + wantLedOnTimeOffTimeSet: []uint8{0x06, 0x99, 0x07, 0x01, 0x08, 0xCC, 0x09, 0x04}, + }, + "example2_datasheet": { + pin: 4, + onCounts: 3685, + offCounts: 3275, + wantLedOnTimeOffTimeSet: []uint8{0x16, 0x65, 0x17, 0x0E, 0x18, 0xCB, 0x19, 0x0C}, + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + // arrange + d, a := initTestPCA9685WithStubbedAdaptor() + a.written = []byte{} // reset writes of former test + // act + err := d.SetPWM(tc.pin, tc.onCounts, tc.offCounts) + // assert + assert.NoError(t, err) + assert.Equal(t, 8, len(a.written)) + for writeIdx, wantVal := range tc.wantLedOnTimeOffTimeSet { + assert.Equal(t, wantVal, a.written[writeIdx], "index %d differs", writeIdx) + } + }) } - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.SetPWM(0, 0, 256), nil) } func TestPCA9685SetPWMError(t *testing.T) { - d, a := initTestPCA9685DriverWithStubbedAdaptor() - a.i2cReadImpl = func(b []byte) (int, error) { - copy(b, []byte{0x01}) - return 1, nil - } - gobottest.Assert(t, d.Start(), nil) + // arrange + d, a := initTestPCA9685WithStubbedAdaptor() a.i2cWriteImpl = func([]byte) (int, error) { return 0, errors.New("write error") } - gobottest.Assert(t, d.SetPWM(0, 0, 256), errors.New("write error")) + // act & assert + assert.ErrorContains(t, d.SetPWM(0, 0, 256), "write error") } -func TestPCA9685SetPWMFreq(t *testing.T) { - d, a := initTestPCA9685DriverWithStubbedAdaptor() - a.i2cReadImpl = func(b []byte) (int, error) { - copy(b, []byte{0x01}) - return 1, nil +func TestPCA9685SetAllPWM(t *testing.T) { + // sequence to set PWM for PCA9685: + // * set LEDn ON-time register (n=0: 0x06, 0x07, n=1: 0x0A, 0x0B ... n=14: 0x3E, 0x3F, n=15: 0x42, 0x43) + // * set LEDn OFF-time register (n=0: 0x08, 0x09, n=1: 0x0C, 0x0D ... n=14: 0x40, 0x41, n=15: 0x44, 0x45) + tests := map[string]struct { + pin byte + onCounts uint16 + offCounts uint16 + wantLedOnTimeOffTimeSet []uint8 + }{ + "example1_datasheet": { + onCounts: 409, + offCounts: 1228, + wantLedOnTimeOffTimeSet: []uint8{0xFA, 0x99, 0xFB, 0x01, 0xFC, 0xCC, 0xFD, 0x04}, + }, + "example2_datasheet": { + onCounts: 3685, + offCounts: 3275, + wantLedOnTimeOffTimeSet: []uint8{0xFA, 0x65, 0xFB, 0x0E, 0xFC, 0xCB, 0xFD, 0x0C}, + }, + "own_example": { + onCounts: 1234, + offCounts: 4321, + wantLedOnTimeOffTimeSet: []uint8{0xFA, 0xD2, 0xFB, 0x04, 0xFC, 0xE1, 0xFD, 0x10}, + }, } - gobottest.Assert(t, d.Start(), nil) - a.i2cReadImpl = func(b []byte) (int, error) { - copy(b, []byte{0x01}) - return 1, nil + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + // arrange + d, a := initTestPCA9685WithStubbedAdaptor() + a.written = []byte{} // reset writes of former test + // act + err := d.SetAllPWM(tc.onCounts, tc.offCounts) + // assert + assert.NoError(t, err) + assert.Equal(t, 8, len(a.written)) + for writeIdx, wantVal := range tc.wantLedOnTimeOffTimeSet { + assert.Equal(t, wantVal, a.written[writeIdx], "index %d differs", writeIdx) + } + }) } - gobottest.Assert(t, d.SetPWMFreq(60), nil) } -func TestPCA9685SetPWMFreqReadError(t *testing.T) { - d, a := initTestPCA9685DriverWithStubbedAdaptor() - a.i2cReadImpl = func(b []byte) (int, error) { - copy(b, []byte{0x01}) - return 1, nil +func TestPCA9685SetAllPWMError(t *testing.T) { + // arrange + d, a := initTestPCA9685WithStubbedAdaptor() + a.i2cWriteImpl = func([]byte) (int, error) { + return 0, errors.New("write error") } - gobottest.Assert(t, d.Start(), nil) + // act & assert + assert.ErrorContains(t, d.SetAllPWM(0, 256), "write error") +} - a.i2cReadImpl = func(b []byte) (int, error) { - return 0, errors.New("read error") +func TestPCA9685SetPWMFreq(t *testing.T) { + // sequence to set PWM frequency prescaler for PCA9685 (can only be set in sleep mode): + // * read MODE1 register (0x00) + // * prepare MODE1 register with sleep mode set (bit 4 - 0x10, no stopping of PWM channels done before) + // * write MODE1 register + // * write the prescaler value to PRE_SCALE register (0xFE) + // * prepare MIODE1 register with sleep mode bit reset + // * write MODE1 register + // * wait > 500us + // * prepare the MODE1 register with set of reset bit + // * write MODE1 register + const readMode1Val = 0x0F // to check for only sleep mode bit (0x10) or reset bit (0x80) will be set + var ( + wantMode1SleepSequence = []uint8{0x00, 0x1F} + wantMode1NoSleepSequence = []uint8{0x00, readMode1Val} + wantMode1ResetSequence = []uint8{0x00, 0x8F} + ) + tests := map[string]struct { + freq float32 + wantPrescalerSequence []uint8 + }{ + "example_datasheet": { + freq: 200, + wantPrescalerSequence: []uint8{0xFE, 0x1E}, + }, + } + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + // arrange + d, a := initTestPCA9685WithStubbedAdaptor() + // arrange read for MODE1 register + numCallsRead := 0 + a.i2cReadImpl = func(b []byte) (int, error) { + numCallsRead++ + b[0] = readMode1Val + return len(b), nil + } + a.written = []byte{} // reset writes of former test + // act + err := d.SetPWMFreq(tc.freq) + // assert + assert.NoError(t, err) + assert.Equal(t, 9, len(a.written)) + var writeIdx int + // for read old mode: + assert.Equal(t, wantMode1SleepSequence[0], a.written[writeIdx], "index %d differs", writeIdx) + writeIdx++ + for idx, wantVal := range wantMode1SleepSequence { + assert.Equal(t, wantVal, a.written[writeIdx], "index %d (%d) differs", writeIdx, idx) + writeIdx++ + } + for idx, wantVal := range tc.wantPrescalerSequence { + assert.Equal(t, wantVal, a.written[writeIdx], "index %d (%d) differs", writeIdx, idx) + writeIdx++ + } + for idx, wantVal := range wantMode1NoSleepSequence { + assert.Equal(t, wantVal, a.written[writeIdx], "index %d (%d) differs", writeIdx, idx) + writeIdx++ + } + for idx, wantVal := range wantMode1ResetSequence { + assert.Equal(t, wantVal, a.written[writeIdx], "index %d (%d) differs", writeIdx, idx) + writeIdx++ + } + assert.Equal(t, 1, numCallsRead) + }) } - gobottest.Assert(t, d.SetPWMFreq(60), errors.New("read error")) } -func TestPCA9685SetPWMFreqWriteError(t *testing.T) { - d, a := initTestPCA9685DriverWithStubbedAdaptor() +func TestPCA9685SetPWMFreqReadError(t *testing.T) { + // arrange + d, a := initTestPCA9685WithStubbedAdaptor() a.i2cReadImpl = func(b []byte) (int, error) { - copy(b, []byte{0x01}) - return 1, nil + return 0, errors.New("read error") } - gobottest.Assert(t, d.Start(), nil) + // act & assert + assert.ErrorContains(t, d.SetPWMFreq(60), "read error") +} +func TestPCA9685SetPWMFreqWriteError(t *testing.T) { + // arrange + d, a := initTestPCA9685WithStubbedAdaptor() a.i2cWriteImpl = func([]byte) (int, error) { return 0, errors.New("write error") } - gobottest.Assert(t, d.SetPWMFreq(60), errors.New("write error")) + // act & assert + assert.ErrorContains(t, d.SetPWMFreq(60), "write error") } func TestPCA9685Commands(t *testing.T) { - d, a := initTestPCA9685DriverWithStubbedAdaptor() + // arrange + d, _ := initTestPCA9685WithStubbedAdaptor() + // act & assert + assert.Nil(t, d.Command("PwmWrite")(map[string]interface{}{"pin": "1", "val": "1"})) + assert.Nil(t, d.Command("ServoWrite")(map[string]interface{}{"pin": "1", "val": "1"})) + assert.Nil(t, d.Command("SetPWM")(map[string]interface{}{"channel": "1", "on": "0", "off": "1024"})) + assert.Nil(t, d.Command("SetPWMFreq")(map[string]interface{}{"freq": "60"})) +} + +func TestPCA9685_initialize(t *testing.T) { + // sequence to reset the PCA9685 in initialize(): + // * set all LED ON-time and OFF-time registers (0xFA..0xFD for 16 channels, each for low and high byte) + // * set MODE2 register (0x01) to defaults: not inverted, outputs change on stop, OE reaction to 0, totem-pole + // * set MODE1 register (0x00) to defaults, except sleep: no restart, internal clock, no AI, no sleep (not default), + // no response to sub address 1, 2 or 3, activate response to all-call + // * wait > 500us, read back the MODE1 register + // * prepare the MODE1 register with set of reset bit + // * write MODE1 register + // arrange + d, a := initTestPCA9685WithStubbedAdaptor() + a.written = []byte{} // reset writes of former test + wantAllLedOnTimeOffTimeSequence := []uint8{0xFA, 0x00, 0xFB, 0x00, 0xFC, 0x00, 0xFD, 0x00} + wantMode2RegSetDefaultsSequence := []uint8{0x01, 0x04} + wantMode1RegSetDefaultsNoSleepSequence := []uint8{0x00, 0x01} + wantMode1RegResetSequence := []uint8{0x00, 0x81} + // arrange read for MODE1 register + numCallsRead := 0 a.i2cReadImpl = func(b []byte) (int, error) { - copy(b, []byte{0x01}) - return 1, nil + numCallsRead++ + b[0] = wantMode1RegSetDefaultsNoSleepSequence[1] + return len(b), nil } - _ = d.Start() - - err := d.Command("PwmWrite")(map[string]interface{}{"pin": "1", "val": "1"}) - gobottest.Assert(t, err, nil) - - err = d.Command("ServoWrite")(map[string]interface{}{"pin": "1", "val": "1"}) - gobottest.Assert(t, err, nil) - - err = d.Command("SetPWM")(map[string]interface{}{"channel": "1", "on": "0", "off": "1024"}) - gobottest.Assert(t, err, nil) - - err = d.Command("SetPWMFreq")(map[string]interface{}{"freq": "60"}) - gobottest.Assert(t, err, nil) + // act, assert - initialize() must be called on Start() + err := d.Start() + // assert + assert.NoError(t, err) + assert.Equal(t, 15, len(a.written)) + var writeIdx int + for idx, wantVal := range wantAllLedOnTimeOffTimeSequence { + assert.Equal(t, wantVal, a.written[writeIdx], "index %d (%d) differs", writeIdx, idx) + writeIdx++ + } + for idx, wantVal := range wantMode2RegSetDefaultsSequence { + assert.Equal(t, wantVal, a.written[writeIdx], "index %d (%d) differs", writeIdx, idx) + writeIdx++ + } + for idx, wantVal := range wantMode1RegSetDefaultsNoSleepSequence { + assert.Equal(t, wantVal, a.written[writeIdx], "index %d (%d) differs", writeIdx, idx) + writeIdx++ + } + // for read old mode: + assert.Equal(t, wantMode1RegSetDefaultsNoSleepSequence[0], a.written[writeIdx], "index %d differs", writeIdx) + writeIdx++ + for idx, wantVal := range wantMode1RegResetSequence { + assert.Equal(t, wantVal, a.written[writeIdx], "index %d (%d) differs", writeIdx, idx) + writeIdx++ + } + assert.Equal(t, 1, numCallsRead) } diff --git a/drivers/i2c/pcf8583_driver.go b/drivers/i2c/pcf8583_driver.go index 89e6be711..2db6821b2 100644 --- a/drivers/i2c/pcf8583_driver.go +++ b/drivers/i2c/pcf8583_driver.go @@ -49,7 +49,7 @@ const ( // 0 1 0 1 0 0 0 A0|rd // Lowest bit (rd) is mapped to switch between write(0)/read(1), it is not part of the "real" address. // -// PCF8583 is mainly compatible to PCF8593, so this driver should also work for PCF8593 except RAM calls +// # PCF8583 is mainly compatible to PCF8593, so this driver should also work for PCF8593 except RAM calls // // This driver was tested with Tinkerboard. type PCF8583Driver struct { @@ -61,13 +61,14 @@ type PCF8583Driver struct { // NewPCF8583Driver creates a new driver with specified i2c interface // Params: -// c Connector - the Adaptor to use with this Driver +// +// c Connector - the Adaptor to use with this Driver // // Optional params: -// i2c.WithBus(int): bus to use with this driver -// i2c.WithAddress(int): address to use with this driver -// i2c.WithPCF8583Mode(PCF8583Control): mode of this driver // +// i2c.WithBus(int): bus to use with this driver +// i2c.WithAddress(int): address to use with this driver +// i2c.WithPCF8583Mode(PCF8583Control): mode of this driver func NewPCF8583Driver(c Connector, options ...func(Config)) *PCF8583Driver { d := &PCF8583Driver{ Driver: NewDriver(c, "PCF8583", pcf8583DefaultAddress), @@ -149,7 +150,8 @@ func (d *PCF8583Driver) WriteTime(val time.Time) error { } year, month, day := val.Date() err = d.connection.WriteBlockData(uint8(pcf8583Reg_CTRL), - []byte{ctrlRegVal | uint8(pcf8583CtrlStopCounting), + []byte{ + ctrlRegVal | uint8(pcf8583CtrlStopCounting), pcf8583encodeBcd(uint8(val.Nanosecond() / 1000000 / 10)), // sub seconds in 1/10th seconds pcf8583encodeBcd(uint8(val.Second())), pcf8583encodeBcd(uint8(val.Minute())), @@ -216,7 +218,8 @@ func (d *PCF8583Driver) WriteCounter(val int32) error { return fmt.Errorf("%s: can't write counter because the device is in wrong mode 0x%02x", d.name, ctrlRegVal) } err = d.connection.WriteBlockData(uint8(pcf8583Reg_CTRL), - []byte{ctrlRegVal | uint8(pcf8583CtrlStopCounting), // stop + []byte{ + ctrlRegVal | uint8(pcf8583CtrlStopCounting), // stop pcf8583encodeBcd(uint8(val % 100)), // 2 lowest digits pcf8583encodeBcd(uint8((val / 100) % 100)), // 2 middle digits pcf8583encodeBcd(uint8((val / 10000) % 100)), // 2 highest digits @@ -329,13 +332,13 @@ func pcf8583encodeBcd(val byte) byte { log.Printf("PCF8583 BCD value (%d) exceeds limit of 99, now limited.", val) } } - hi, lo := byte(val/10), byte(val%10) + hi, lo := val/10, val%10 return hi<<4 | lo } func pcf8583decodeBcd(bcd byte) byte { // 0x12 => decimal 12 - hi, lo := byte(bcd>>4), byte(bcd&0x0f) + hi, lo := bcd>>4, bcd&0x0f if hi > 9 { hi = 9 if pcf8583Debug { diff --git a/drivers/i2c/pcf8583_driver_test.go b/drivers/i2c/pcf8583_driver_test.go index c0a6db1d9..e37c26753 100644 --- a/drivers/i2c/pcf8583_driver_test.go +++ b/drivers/i2c/pcf8583_driver_test.go @@ -5,8 +5,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -26,20 +26,20 @@ func TestNewPCF8583Driver(t *testing.T) { if !ok { t.Errorf("NewPCF8583Driver() should have returned a *PCF8583Driver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.name, "PCF8583"), true) - gobottest.Assert(t, d.defaultAddress, 0x50) - gobottest.Assert(t, d.mode, PCF8583Control(0x00)) - gobottest.Assert(t, d.yearOffset, 0) - gobottest.Assert(t, d.ramOffset, uint8(0x10)) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.name, "PCF8583")) + assert.Equal(t, 0x50, d.defaultAddress) + assert.Equal(t, PCF8583Control(0x00), d.mode) + assert.Equal(t, 0, d.yearOffset) + assert.Equal(t, uint8(0x10), d.ramOffset) } func TestPCF8583Options(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option and // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". d := NewPCF8583Driver(newI2cTestAdaptor(), WithBus(2), WithPCF8583Mode(PCF8583CtrlModeClock50)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) - gobottest.Assert(t, d.mode, PCF8583CtrlModeClock50) + assert.Equal(t, 2, d.GetBusOrDefault(1)) + assert.Equal(t, PCF8583CtrlModeClock50, d.mode) } func TestPCF8583CommandsWriteTime(t *testing.T) { @@ -60,7 +60,7 @@ func TestPCF8583CommandsWriteTime(t *testing.T) { // act result := d.Command("WriteTime")(map[string]interface{}{"val": time.Now()}) // assert - gobottest.Assert(t, result.(map[string]interface{})["err"], nil) + assert.Nil(t, result.(map[string]interface{})["err"]) } func TestPCF8583CommandsReadTime(t *testing.T) { @@ -68,7 +68,7 @@ func TestPCF8583CommandsReadTime(t *testing.T) { d, a := initTestPCF8583WithStubbedAdaptor() d.yearOffset = 2019 milliSec := 550 * time.Millisecond // 0.55 sec = 550 ms - want := time.Date(2021, time.December, 24, 18, 00, 00, int(milliSec), time.UTC) + want := time.Date(2021, time.December, 24, 18, 0, 0, int(milliSec), time.UTC) reg0Val := uint8(0x00) // clock mode 32.768 kHz reg1Val := uint8(0x55) // BCD: 1/10 and 1/100 sec (55) reg2Val := uint8(0x00) // BCD: 10 and 1 sec (00) @@ -94,8 +94,8 @@ func TestPCF8583CommandsReadTime(t *testing.T) { // act result := d.Command("ReadTime")(map[string]interface{}{}) // assert - gobottest.Assert(t, result.(map[string]interface{})["err"], nil) - gobottest.Assert(t, result.(map[string]interface{})["val"], want) + assert.Nil(t, result.(map[string]interface{})["err"]) + assert.Equal(t, want, result.(map[string]interface{})["val"]) } func TestPCF8583CommandsWriteCounter(t *testing.T) { @@ -116,7 +116,7 @@ func TestPCF8583CommandsWriteCounter(t *testing.T) { // act result := d.Command("WriteCounter")(map[string]interface{}{"val": int32(123456)}) // assert - gobottest.Assert(t, result.(map[string]interface{})["err"], nil) + assert.Nil(t, result.(map[string]interface{})["err"]) } func TestPCF8583CommandsReadCounter(t *testing.T) { @@ -145,34 +145,34 @@ func TestPCF8583CommandsReadCounter(t *testing.T) { // act result := d.Command("ReadCounter")(map[string]interface{}{}) // assert - gobottest.Assert(t, result.(map[string]interface{})["err"], nil) - gobottest.Assert(t, result.(map[string]interface{})["val"], want) + assert.Nil(t, result.(map[string]interface{})["err"]) + assert.Equal(t, want, result.(map[string]interface{})["val"]) } func TestPCF8583CommandsWriteRAM(t *testing.T) { // arrange d, _ := initTestPCF8583WithStubbedAdaptor() - var addressValue = map[string]interface{}{ + addressValue := map[string]interface{}{ "address": uint8(0x12), "val": uint8(0x45), } // act result := d.Command("WriteRAM")(addressValue) // assert - gobottest.Assert(t, result.(map[string]interface{})["err"], nil) + assert.Nil(t, result.(map[string]interface{})["err"]) } func TestPCF8583CommandsReadRAM(t *testing.T) { // arrange d, _ := initTestPCF8583WithStubbedAdaptor() - var address = map[string]interface{}{ + address := map[string]interface{}{ "address": uint8(0x34), } // act result := d.Command("ReadRAM")(address) // assert - gobottest.Assert(t, result.(map[string]interface{})["err"], nil) - gobottest.Assert(t, result.(map[string]interface{})["val"], uint8(0)) + assert.Nil(t, result.(map[string]interface{})["err"]) + assert.Equal(t, uint8(0), result.(map[string]interface{})["val"]) } func TestPCF8583WriteTime(t *testing.T) { @@ -210,21 +210,21 @@ func TestPCF8583WriteTime(t *testing.T) { // act err := d.WriteTime(initDate) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, d.yearOffset, initDate.Year()) - gobottest.Assert(t, numCallsRead, 1) - gobottest.Assert(t, len(a.written), 11) - gobottest.Assert(t, a.written[0], uint8(pcf8583Reg_CTRL)) - gobottest.Assert(t, a.written[1], uint8(pcf8583Reg_CTRL)) - gobottest.Assert(t, a.written[2], wantCtrlStop) - gobottest.Assert(t, a.written[3], wantReg1Val) - gobottest.Assert(t, a.written[4], wantReg2Val) - gobottest.Assert(t, a.written[5], wantReg3Val) - gobottest.Assert(t, a.written[6], wantReg4Val) - gobottest.Assert(t, a.written[7], wantReg5Val) - gobottest.Assert(t, a.written[8], wantReg6Val) - gobottest.Assert(t, a.written[9], uint8(pcf8583Reg_CTRL)) - gobottest.Assert(t, a.written[10], wantCrtlStart) + assert.NoError(t, err) + assert.Equal(t, initDate.Year(), d.yearOffset) + assert.Equal(t, 1, numCallsRead) + assert.Equal(t, 11, len(a.written)) + assert.Equal(t, uint8(pcf8583Reg_CTRL), a.written[0]) + assert.Equal(t, uint8(pcf8583Reg_CTRL), a.written[1]) + assert.Equal(t, wantCtrlStop, a.written[2]) + assert.Equal(t, wantReg1Val, a.written[3]) + assert.Equal(t, wantReg2Val, a.written[4]) + assert.Equal(t, wantReg3Val, a.written[5]) + assert.Equal(t, wantReg4Val, a.written[6]) + assert.Equal(t, wantReg5Val, a.written[7]) + assert.Equal(t, wantReg6Val, a.written[8]) + assert.Equal(t, uint8(pcf8583Reg_CTRL), a.written[9]) + assert.Equal(t, wantCrtlStart, a.written[10]) } func TestPCF8583WriteTimeNoTimeModeFails(t *testing.T) { @@ -246,11 +246,11 @@ func TestPCF8583WriteTimeNoTimeModeFails(t *testing.T) { // act err := d.WriteTime(time.Now()) // assert - gobottest.Refute(t, err, nil) - gobottest.Assert(t, strings.Contains(err.Error(), "wrong mode 0x30"), true) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], uint8(pcf8583Reg_CTRL)) - gobottest.Assert(t, numCallsRead, 1) + assert.NotNil(t, err) + assert.Contains(t, err.Error(), "wrong mode 0x30") + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, uint8(pcf8583Reg_CTRL), a.written[0]) + assert.Equal(t, 1, numCallsRead) } func TestPCF8583ReadTime(t *testing.T) { @@ -292,11 +292,11 @@ func TestPCF8583ReadTime(t *testing.T) { // act got, err := d.ReadTime() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], uint8(pcf8583Reg_CTRL)) - gobottest.Assert(t, numCallsRead, 2) - gobottest.Assert(t, got, want) + assert.NoError(t, err) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, uint8(pcf8583Reg_CTRL), a.written[0]) + assert.Equal(t, 2, numCallsRead) + assert.Equal(t, want, got) } func TestPCF8583ReadTimeNoTimeModeFails(t *testing.T) { @@ -318,12 +318,12 @@ func TestPCF8583ReadTimeNoTimeModeFails(t *testing.T) { // act got, err := d.ReadTime() // assert - gobottest.Refute(t, err, nil) - gobottest.Assert(t, strings.Contains(err.Error(), "wrong mode 0x20"), true) - gobottest.Assert(t, got, time.Time{}) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], uint8(pcf8583Reg_CTRL)) - gobottest.Assert(t, numCallsRead, 1) + assert.NotNil(t, err) + assert.Contains(t, err.Error(), "wrong mode 0x20") + assert.Equal(t, time.Time{}, got) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, uint8(pcf8583Reg_CTRL), a.written[0]) + assert.Equal(t, 1, numCallsRead) } func TestPCF8583WriteCounter(t *testing.T) { @@ -357,17 +357,17 @@ func TestPCF8583WriteCounter(t *testing.T) { // act err := d.WriteCounter(initCount) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, numCallsRead, 1) - gobottest.Assert(t, len(a.written), 8) - gobottest.Assert(t, a.written[0], uint8(pcf8583Reg_CTRL)) - gobottest.Assert(t, a.written[1], uint8(pcf8583Reg_CTRL)) - gobottest.Assert(t, a.written[2], wantCtrlStop) - gobottest.Assert(t, a.written[3], wantReg1Val) - gobottest.Assert(t, a.written[4], wantReg2Val) - gobottest.Assert(t, a.written[5], wantReg3Val) - gobottest.Assert(t, a.written[6], uint8(pcf8583Reg_CTRL)) - gobottest.Assert(t, a.written[7], wantCtrlStart) + assert.NoError(t, err) + assert.Equal(t, 1, numCallsRead) + assert.Equal(t, 8, len(a.written)) + assert.Equal(t, uint8(pcf8583Reg_CTRL), a.written[0]) + assert.Equal(t, uint8(pcf8583Reg_CTRL), a.written[1]) + assert.Equal(t, wantCtrlStop, a.written[2]) + assert.Equal(t, wantReg1Val, a.written[3]) + assert.Equal(t, wantReg2Val, a.written[4]) + assert.Equal(t, wantReg3Val, a.written[5]) + assert.Equal(t, uint8(pcf8583Reg_CTRL), a.written[6]) + assert.Equal(t, wantCtrlStart, a.written[7]) } func TestPCF8583WriteCounterNoCounterModeFails(t *testing.T) { @@ -389,11 +389,11 @@ func TestPCF8583WriteCounterNoCounterModeFails(t *testing.T) { // act err := d.WriteCounter(123) // assert - gobottest.Refute(t, err, nil) - gobottest.Assert(t, strings.Contains(err.Error(), "wrong mode 0x10"), true) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], uint8(pcf8583Reg_CTRL)) - gobottest.Assert(t, numCallsRead, 1) + assert.NotNil(t, err) + assert.Contains(t, err.Error(), "wrong mode 0x10") + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, uint8(pcf8583Reg_CTRL), a.written[0]) + assert.Equal(t, 1, numCallsRead) } func TestPCF8583ReadCounter(t *testing.T) { @@ -430,11 +430,11 @@ func TestPCF8583ReadCounter(t *testing.T) { // act got, err := d.ReadCounter() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], uint8(pcf8583Reg_CTRL)) - gobottest.Assert(t, numCallsRead, 2) - gobottest.Assert(t, got, want) + assert.NoError(t, err) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, uint8(pcf8583Reg_CTRL), a.written[0]) + assert.Equal(t, 2, numCallsRead) + assert.Equal(t, want, got) } func TestPCF8583ReadCounterNoCounterModeFails(t *testing.T) { @@ -456,12 +456,12 @@ func TestPCF8583ReadCounterNoCounterModeFails(t *testing.T) { // act got, err := d.ReadCounter() // assert - gobottest.Refute(t, err, nil) - gobottest.Assert(t, strings.Contains(err.Error(), "wrong mode 0x30"), true) - gobottest.Assert(t, got, int32(0)) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], uint8(pcf8583Reg_CTRL)) - gobottest.Assert(t, numCallsRead, 1) + assert.NotNil(t, err) + assert.Contains(t, err.Error(), "wrong mode 0x30") + assert.Equal(t, int32(0), got) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, uint8(pcf8583Reg_CTRL), a.written[0]) + assert.Equal(t, 1, numCallsRead) } func TestPCF8583WriteRam(t *testing.T) { @@ -480,10 +480,10 @@ func TestPCF8583WriteRam(t *testing.T) { // act err := d.WriteRAM(wantRAMAddress-pcf8583RamOffset, wantRAMValue) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 2) - gobottest.Assert(t, a.written[0], wantRAMAddress) - gobottest.Assert(t, a.written[1], wantRAMValue) + assert.NoError(t, err) + assert.Equal(t, 2, len(a.written)) + assert.Equal(t, wantRAMAddress, a.written[0]) + assert.Equal(t, wantRAMValue, a.written[1]) } func TestPCF8583WriteRamAddressOverflowFails(t *testing.T) { @@ -493,9 +493,9 @@ func TestPCF8583WriteRamAddressOverflowFails(t *testing.T) { // act err := d.WriteRAM(uint8(0xF0), 15) // assert - gobottest.Refute(t, err, nil) - gobottest.Assert(t, strings.Contains(err.Error(), "overflow 256"), true) - gobottest.Assert(t, len(a.written), 0) + assert.NotNil(t, err) + assert.Contains(t, err.Error(), "overflow 256") + assert.Equal(t, 0, len(a.written)) } func TestPCF8583ReadRam(t *testing.T) { @@ -521,11 +521,11 @@ func TestPCF8583ReadRam(t *testing.T) { // act got, err := d.ReadRAM(wantRAMAddress - pcf8583RamOffset) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, got, want) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], wantRAMAddress) - gobottest.Assert(t, numCallsRead, 1) + assert.NoError(t, err) + assert.Equal(t, want, got) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, wantRAMAddress, a.written[0]) + assert.Equal(t, 1, numCallsRead) } func TestPCF8583ReadRamAddressOverflowFails(t *testing.T) { @@ -545,11 +545,11 @@ func TestPCF8583ReadRamAddressOverflowFails(t *testing.T) { // act got, err := d.ReadRAM(uint8(0xF0)) // assert - gobottest.Refute(t, err, nil) - gobottest.Assert(t, strings.Contains(err.Error(), "overflow 256"), true) - gobottest.Assert(t, got, uint8(0)) - gobottest.Assert(t, len(a.written), 0) - gobottest.Assert(t, numCallsRead, 0) + assert.NotNil(t, err) + assert.Contains(t, err.Error(), "overflow 256") + assert.Equal(t, uint8(0), got) + assert.Equal(t, 0, len(a.written)) + assert.Equal(t, 0, numCallsRead) } func TestPCF8583_initializeNoModeSwitch(t *testing.T) { @@ -572,10 +572,10 @@ func TestPCF8583_initializeNoModeSwitch(t *testing.T) { // act, assert - initialize() must be called on Start() err := d.Start() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, numCallsRead, 1) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], uint8(pcf8583Reg_CTRL)) + assert.NoError(t, err) + assert.Equal(t, 1, numCallsRead) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, uint8(pcf8583Reg_CTRL), a.written[0]) } func TestPCF8583_initializeWithModeSwitch(t *testing.T) { @@ -604,10 +604,10 @@ func TestPCF8583_initializeWithModeSwitch(t *testing.T) { // act, assert - initialize() must be called on Start() err := d.Start() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, numCallsRead, 1) - gobottest.Assert(t, len(a.written), 3) - gobottest.Assert(t, a.written[0], uint8(pcf8583Reg_CTRL)) - gobottest.Assert(t, a.written[1], uint8(pcf8583Reg_CTRL)) - gobottest.Assert(t, a.written[2], uint8(wantReg0Val)) + assert.NoError(t, err) + assert.Equal(t, 1, numCallsRead) + assert.Equal(t, 3, len(a.written)) + assert.Equal(t, uint8(pcf8583Reg_CTRL), a.written[0]) + assert.Equal(t, uint8(pcf8583Reg_CTRL), a.written[1]) + assert.Equal(t, wantReg0Val, a.written[2]) } diff --git a/drivers/i2c/pcf8591_driver.go b/drivers/i2c/pcf8591_driver.go index b62942734..e686429ad 100644 --- a/drivers/i2c/pcf8591_driver.go +++ b/drivers/i2c/pcf8591_driver.go @@ -15,8 +15,10 @@ const ( pcf8591Debug = false ) -type pcf8591Mode uint8 -type PCF8591Channel uint8 +type ( + pcf8591Mode uint8 + PCF8591Channel uint8 +) const ( pcf8591_CHAN0 PCF8591Channel = 0x00 @@ -96,7 +98,6 @@ var pcf8591ModeMap = map[string]pcf8591ModeChan{ // https://www.adafruit.com/product/4648 // // This driver was tested with Tinkerboard and the YL-40 driver. -// type PCF8591Driver struct { *Driver lastCtrlByte byte @@ -109,13 +110,14 @@ type PCF8591Driver struct { // NewPCF8591Driver creates a new driver with specified i2c interface // Params: -// c Connector - the Adaptor to use with this Driver +// +// c Connector - the Adaptor to use with this Driver // // Optional params: -// i2c.WithBus(int): bus to use with this driver -// i2c.WithAddress(int): address to use with this driver -// i2c.WithPCF8591With400kbitStabilization(uint8, uint8): stabilize read in 400 kbit mode // +// i2c.WithBus(int): bus to use with this driver +// i2c.WithAddress(int): address to use with this driver +// i2c.WithPCF8591With400kbitStabilization(uint8, uint8): stabilize read in 400 kbit mode func NewPCF8591Driver(c Connector, options ...func(Config)) *PCF8591Driver { p := &PCF8591Driver{ Driver: NewDriver(c, "PCF8591", pcf8591DefaultAddress), @@ -182,11 +184,11 @@ func WithPCF8591ForceRefresh(val uint8) func(Config) { // An i2c bus extender (LTC4311) don't fix it (it seems rather the opposite). // // This leads to following behavior: -// * the control byte is not written correctly -// * the transition process takes an additional cycle, very often -// * some circuits takes one cycle longer transition time in addition -// * reading more than one byte by Read([]byte), e.g. to calculate an average, is not sufficient, -// because some missing integration steps in each conversion (each byte value is a little bit lower than expected) +// - the control byte is not written correctly +// - the transition process takes an additional cycle, very often +// - some circuits takes one cycle longer transition time in addition +// - reading more than one byte by Read([]byte), e.g. to calculate an average, is not sufficient, +// because some missing integration steps in each conversion (each byte value is a little bit lower than expected) // // So, for default, we drop the first three bytes to get the right value. func (p *PCF8591Driver) AnalogRead(description string) (value int, err error) { diff --git a/drivers/i2c/pcf8591_driver_test.go b/drivers/i2c/pcf8591_driver_test.go index d00f5de68..299d49f2c 100644 --- a/drivers/i2c/pcf8591_driver_test.go +++ b/drivers/i2c/pcf8591_driver_test.go @@ -4,8 +4,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -28,25 +28,25 @@ func TestNewPCF8591Driver(t *testing.T) { if !ok { t.Errorf("NewPCF8591Driver() should have returned a *PCF8591Driver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "PCF8591"), true) - gobottest.Assert(t, d.defaultAddress, 0x48) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "PCF8591")) + assert.Equal(t, 0x48, d.defaultAddress) } func TestPCF8591Start(t *testing.T) { d := NewPCF8591Driver(newI2cTestAdaptor()) - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestPCF8591Halt(t *testing.T) { d := NewPCF8591Driver(newI2cTestAdaptor()) - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestPCF8591WithPCF8591With400kbitStabilization(t *testing.T) { d := NewPCF8591Driver(newI2cTestAdaptor(), WithPCF8591With400kbitStabilization(5, 6)) - gobottest.Assert(t, d.additionalReadWrite, uint8(5)) - gobottest.Assert(t, d.additionalRead, uint8(6)) + assert.Equal(t, uint8(5), d.additionalReadWrite) + assert.Equal(t, uint8(6), d.additionalRead) } func TestPCF8591AnalogReadSingle(t *testing.T) { @@ -78,11 +78,11 @@ func TestPCF8591AnalogReadSingle(t *testing.T) { // act got, err := d.AnalogRead(description) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], ctrlByteOn) - gobottest.Assert(t, numCallsRead, 2) - gobottest.Assert(t, got, want) + assert.NoError(t, err) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, ctrlByteOn, a.written[0]) + assert.Equal(t, 2, numCallsRead) + assert.Equal(t, want, got) } func TestPCF8591AnalogReadDiff(t *testing.T) { @@ -120,11 +120,11 @@ func TestPCF8591AnalogReadDiff(t *testing.T) { // act got, err := d.AnalogRead(description) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], ctrlByteOn) - gobottest.Assert(t, numCallsRead, 2) - gobottest.Assert(t, got, want) + assert.NoError(t, err) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, ctrlByteOn, a.written[0]) + assert.Equal(t, 2, numCallsRead) + assert.Equal(t, want, got) } func TestPCF8591AnalogWrite(t *testing.T) { @@ -146,10 +146,10 @@ func TestPCF8591AnalogWrite(t *testing.T) { // act err := d.AnalogWrite("", int(want)) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 2) - gobottest.Assert(t, a.written[0], ctrlByteOn) - gobottest.Assert(t, a.written[1], want) + assert.NoError(t, err) + assert.Equal(t, 2, len(a.written)) + assert.Equal(t, ctrlByteOn, a.written[0]) + assert.Equal(t, want, a.written[1]) } func TestPCF8591AnalogOutputState(t *testing.T) { @@ -171,8 +171,8 @@ func TestPCF8591AnalogOutputState(t *testing.T) { // act err := d.AnalogOutputState(bitState == 1) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], wantCtrlByteVal) + assert.NoError(t, err) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, wantCtrlByteVal, a.written[0]) } } diff --git a/drivers/i2c/sht2x_driver.go b/drivers/i2c/sht2x_driver.go index 3c1e36e1e..abbf376b6 100644 --- a/drivers/i2c/sht2x_driver.go +++ b/drivers/i2c/sht2x_driver.go @@ -165,10 +165,10 @@ func (d *SHT2xDriver) readSensor(cmd byte) (read uint16, err error) { return } - //Hang out while measurement is taken. 85ms max, page 9 of datasheet. + // Hang out while measurement is taken. 85ms max, page 9 of datasheet. time.Sleep(85 * time.Millisecond) - //Comes back in three bytes, data(MSB) / data(LSB) / Checksum + // Comes back in three bytes, data(MSB) / data(LSB) / Checksum buf := make([]byte, 3) counter := 0 for { @@ -188,7 +188,7 @@ func (d *SHT2xDriver) readSensor(cmd byte) (read uint16, err error) { time.Sleep(1 * time.Millisecond) } - //Store the result + // Store the result crc := crc8.Checksum(buf[0:2], d.crcTable) if buf[2] != crc { err = errors.New("Invalid crc") @@ -221,12 +221,12 @@ func (d *SHT2xDriver) sendAccuracy() error { return err } - userRegister &= 0x7e //Turn off the resolution bits + userRegister &= 0x7e // Turn off the resolution bits acc := d.accuracy - acc &= 0x81 //Turn off all other bits but resolution bits - userRegister |= acc //Mask in the requested resolution bits + acc &= 0x81 // Turn off all other bits but resolution bits + userRegister |= acc // Mask in the requested resolution bits - //Request a write to user register + // Request a write to user register if _, err := d.connection.Write([]byte{SHT2xWriteUserReg, userRegister}); err != nil { return err } diff --git a/drivers/i2c/sht2x_driver_test.go b/drivers/i2c/sht2x_driver_test.go index 2578c6757..a71509b0e 100644 --- a/drivers/i2c/sht2x_driver_test.go +++ b/drivers/i2c/sht2x_driver_test.go @@ -2,12 +2,11 @@ package i2c import ( "bytes" - "errors" "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -29,26 +28,26 @@ func TestNewSHT2xDriver(t *testing.T) { if !ok { t.Errorf("NewSHT2xDriver() should have returned a *SHT2xDriver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "SHT2x"), true) - gobottest.Assert(t, d.defaultAddress, 0x40) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "SHT2x")) + assert.Equal(t, 0x40, d.defaultAddress) } func TestSHT2xOptions(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option and // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". b := NewSHT2xDriver(newI2cTestAdaptor(), WithBus(2)) - gobottest.Assert(t, b.GetBusOrDefault(1), 2) + assert.Equal(t, 2, b.GetBusOrDefault(1)) } func TestSHT2xStart(t *testing.T) { d := NewSHT2xDriver(newI2cTestAdaptor()) - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestSHT2xHalt(t *testing.T) { d, _ := initTestSHT2xDriverWithStubbedAdaptor() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestSHT2xReset(t *testing.T) { @@ -58,7 +57,7 @@ func TestSHT2xReset(t *testing.T) { } _ = d.Start() err := d.Reset() - gobottest.Assert(t, err, nil) + assert.NoError(t, err) } func TestSHT2xMeasurements(t *testing.T) { @@ -76,11 +75,11 @@ func TestSHT2xMeasurements(t *testing.T) { } _ = d.Start() temp, err := d.Temperature() - gobottest.Assert(t, err, nil) - gobottest.Assert(t, temp, float32(18.809052)) + assert.NoError(t, err) + assert.Equal(t, float32(18.809052), temp) hum, err := d.Humidity() - gobottest.Assert(t, err, nil) - gobottest.Assert(t, hum, float32(40.279907)) + assert.NoError(t, err) + assert.Equal(t, float32(40.279907), hum) } func TestSHT2xAccuracy(t *testing.T) { @@ -99,9 +98,9 @@ func TestSHT2xAccuracy(t *testing.T) { } _ = d.Start() _ = d.SetAccuracy(SHT2xAccuracyLow) - gobottest.Assert(t, d.Accuracy(), SHT2xAccuracyLow) + assert.Equal(t, SHT2xAccuracyLow, d.Accuracy()) err := d.sendAccuracy() - gobottest.Assert(t, err, nil) + assert.NoError(t, err) } func TestSHT2xTemperatureCrcError(t *testing.T) { @@ -117,8 +116,8 @@ func TestSHT2xTemperatureCrcError(t *testing.T) { return buf.Len(), nil } temp, err := d.Temperature() - gobottest.Assert(t, err, errors.New("Invalid crc")) - gobottest.Assert(t, temp, float32(0.0)) + assert.ErrorContains(t, err, "Invalid crc") + assert.Equal(t, float32(0.0), temp) } func TestSHT2xHumidityCrcError(t *testing.T) { @@ -134,8 +133,8 @@ func TestSHT2xHumidityCrcError(t *testing.T) { return buf.Len(), nil } hum, err := d.Humidity() - gobottest.Assert(t, err, errors.New("Invalid crc")) - gobottest.Assert(t, hum, float32(0.0)) + assert.ErrorContains(t, err, "Invalid crc") + assert.Equal(t, float32(0.0), hum) } func TestSHT2xTemperatureLengthError(t *testing.T) { @@ -151,8 +150,8 @@ func TestSHT2xTemperatureLengthError(t *testing.T) { return buf.Len(), nil } temp, err := d.Temperature() - gobottest.Assert(t, err, ErrNotEnoughBytes) - gobottest.Assert(t, temp, float32(0.0)) + assert.Equal(t, ErrNotEnoughBytes, err) + assert.Equal(t, float32(0.0), temp) } func TestSHT2xHumidityLengthError(t *testing.T) { @@ -168,6 +167,6 @@ func TestSHT2xHumidityLengthError(t *testing.T) { return buf.Len(), nil } hum, err := d.Humidity() - gobottest.Assert(t, err, ErrNotEnoughBytes) - gobottest.Assert(t, hum, float32(0.0)) + assert.Equal(t, ErrNotEnoughBytes, err) + assert.Equal(t, float32(0.0), hum) } diff --git a/drivers/i2c/sht3x_driver_test.go b/drivers/i2c/sht3x_driver_test.go index 522b66b9f..29144a957 100644 --- a/drivers/i2c/sht3x_driver_test.go +++ b/drivers/i2c/sht3x_driver_test.go @@ -5,8 +5,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -28,26 +28,26 @@ func TestNewSHT3xDriver(t *testing.T) { if !ok { t.Errorf("NewSHT3xDriver() should have returned a *SHT3xDriver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "SHT3x"), true) - gobottest.Assert(t, d.defaultAddress, 0x44) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "SHT3x")) + assert.Equal(t, 0x44, d.defaultAddress) } func TestSHT3xOptions(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option and // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". d := NewSHT3xDriver(newI2cTestAdaptor(), WithBus(2)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) + assert.Equal(t, 2, d.GetBusOrDefault(1)) } func TestSHT3xStart(t *testing.T) { d := NewSHT3xDriver(newI2cTestAdaptor()) - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestSHT3xHalt(t *testing.T) { d, _ := initTestSHT3xDriverWithStubbedAdaptor() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestSHT3xSampleNormal(t *testing.T) { @@ -58,13 +58,13 @@ func TestSHT3xSampleNormal(t *testing.T) { } temp, rh, _ := d.Sample() - gobottest.Assert(t, temp, float32(85.523003)) - gobottest.Assert(t, rh, float32(74.5845)) + assert.Equal(t, float32(85.523003), temp) + assert.Equal(t, float32(74.5845), rh) // check the temp with the units in F d.Units = "F" temp, _, _ = d.Sample() - gobottest.Assert(t, temp, float32(185.9414)) + assert.Equal(t, float32(185.9414), temp) } func TestSHT3xSampleBadCrc(t *testing.T) { @@ -76,7 +76,7 @@ func TestSHT3xSampleBadCrc(t *testing.T) { } _, _, err := d.Sample() - gobottest.Assert(t, err, ErrInvalidCrc) + assert.Equal(t, ErrInvalidCrc, err) // Check that the 2nd crc failure is caught a.i2cReadImpl = func(b []byte) (int, error) { @@ -85,7 +85,7 @@ func TestSHT3xSampleBadCrc(t *testing.T) { } _, _, err = d.Sample() - gobottest.Assert(t, err, ErrInvalidCrc) + assert.Equal(t, ErrInvalidCrc, err) } func TestSHT3xSampleBadRead(t *testing.T) { @@ -97,7 +97,7 @@ func TestSHT3xSampleBadRead(t *testing.T) { } _, _, err := d.Sample() - gobottest.Assert(t, err, ErrNotEnoughBytes) + assert.Equal(t, ErrNotEnoughBytes, err) } func TestSHT3xSampleUnits(t *testing.T) { @@ -110,7 +110,7 @@ func TestSHT3xSampleUnits(t *testing.T) { d.Units = "K" _, _, err := d.Sample() - gobottest.Assert(t, err, ErrInvalidTemp) + assert.Equal(t, ErrInvalidTemp, err) } // Test internal sendCommandDelayGetResponse @@ -126,7 +126,7 @@ func TestSHT3xSCDGRIoFailures(t *testing.T) { } _, err := d.sendCommandDelayGetResponse(nil, nil, 2) - gobottest.Assert(t, err, ErrNotEnoughBytes) + assert.Equal(t, ErrNotEnoughBytes, err) // Don't read any bytes and return an error a.i2cReadImpl = func([]byte) (int, error) { @@ -134,7 +134,7 @@ func TestSHT3xSCDGRIoFailures(t *testing.T) { } _, err = d.sendCommandDelayGetResponse(nil, nil, 1) - gobottest.Assert(t, err, invalidRead) + assert.Equal(t, invalidRead, err) // Don't write any bytes and return an error a.i2cWriteImpl = func([]byte) (int, error) { @@ -142,7 +142,7 @@ func TestSHT3xSCDGRIoFailures(t *testing.T) { } _, err = d.sendCommandDelayGetResponse(nil, nil, 1) - gobottest.Assert(t, err, invalidWrite) + assert.Equal(t, invalidWrite, err) } // Test Heater and getStatusRegister @@ -155,8 +155,8 @@ func TestSHT3xHeater(t *testing.T) { } status, err := d.Heater() - gobottest.Assert(t, err, nil) - gobottest.Assert(t, status, true) + assert.NoError(t, err) + assert.True(t, status) // heater disabled a.i2cReadImpl = func(b []byte) (int, error) { @@ -165,8 +165,8 @@ func TestSHT3xHeater(t *testing.T) { } status, err = d.Heater() - gobottest.Assert(t, err, nil) - gobottest.Assert(t, status, false) + assert.NoError(t, err) + assert.False(t, status) // heater crc failed a.i2cReadImpl = func(b []byte) (int, error) { @@ -175,7 +175,7 @@ func TestSHT3xHeater(t *testing.T) { } _, err = d.Heater() - gobottest.Assert(t, err, ErrInvalidCrc) + assert.Equal(t, ErrInvalidCrc, err) // heater read failed a.i2cReadImpl = func(b []byte) (int, error) { @@ -184,7 +184,7 @@ func TestSHT3xHeater(t *testing.T) { } _, err = d.Heater() - gobottest.Refute(t, err, nil) + assert.NotNil(t, err) } func TestSHT3xSetHeater(t *testing.T) { @@ -196,18 +196,18 @@ func TestSHT3xSetHeater(t *testing.T) { func TestSHT3xSetAccuracy(t *testing.T) { d, _ := initTestSHT3xDriverWithStubbedAdaptor() - gobottest.Assert(t, d.Accuracy(), byte(SHT3xAccuracyHigh)) + assert.Equal(t, byte(SHT3xAccuracyHigh), d.Accuracy()) err := d.SetAccuracy(SHT3xAccuracyMedium) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, d.Accuracy(), byte(SHT3xAccuracyMedium)) + assert.NoError(t, err) + assert.Equal(t, byte(SHT3xAccuracyMedium), d.Accuracy()) err = d.SetAccuracy(SHT3xAccuracyLow) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, d.Accuracy(), byte(SHT3xAccuracyLow)) + assert.NoError(t, err) + assert.Equal(t, byte(SHT3xAccuracyLow), d.Accuracy()) err = d.SetAccuracy(0xff) - gobottest.Assert(t, err, ErrInvalidAccuracy) + assert.Equal(t, ErrInvalidAccuracy, err) } func TestSHT3xSerialNumber(t *testing.T) { @@ -219,6 +219,6 @@ func TestSHT3xSerialNumber(t *testing.T) { sn, err := d.SerialNumber() - gobottest.Assert(t, err, nil) - gobottest.Assert(t, sn, uint32(0x2000beef)) + assert.NoError(t, err) + assert.Equal(t, uint32(0x2000beef), sn) } diff --git a/drivers/i2c/ssd1306_driver.go b/drivers/i2c/ssd1306_driver.go index 157d21536..9a8e92944 100644 --- a/drivers/i2c/ssd1306_driver.go +++ b/drivers/i2c/ssd1306_driver.go @@ -26,13 +26,13 @@ const ( ssd1306SetComOutput8 = 0xC8 ssd1306SetContrast = 0x81 // scrolling commands - //ssd1306ContinuousHScrollRight = 0x26 - //ssd1306ContinuousHScrollLeft = 0x27 - //ssd1306ContinuousVHScrollRight = 0x29 - //ssd1306ContinuousVHScrollLeft = 0x2A - //ssd1306StopScroll = 0x2E - //ssd1306StartScroll = 0x2F - // adressing settings commands + // ssd1306ContinuousHScrollRight = 0x26 + // ssd1306ContinuousHScrollLeft = 0x27 + // ssd1306ContinuousVHScrollRight = 0x29 + // ssd1306ContinuousVHScrollLeft = 0x2A + // ssd1306StopScroll = 0x2E + // ssd1306StartScroll = 0x2F + // addressing settings commands ssd1306SetMemoryAddressingMode = 0x20 ssd1306ColumnAddr = 0x21 ssd1306PageAddr = 0x22 @@ -235,14 +235,14 @@ func NewSSD1306Driver(c Connector, options ...func(Config)) *SSD1306Driver { return map[string]interface{}{} }) s.AddCommand("SetContrast", func(params map[string]interface{}) interface{} { - contrast := byte(params["contrast"].(byte)) + contrast := params["contrast"].(byte) err := s.SetContrast(contrast) return map[string]interface{}{"err": err} }) s.AddCommand("Set", func(params map[string]interface{}) interface{} { - x := int(params["x"].(int)) - y := int(params["y"].(int)) - c := int(params["c"].(int)) + x := params["x"].(int) + y := params["y"].(int) + c := params["c"].(int) s.Set(x, y, c) return nil }) diff --git a/drivers/i2c/ssd1306_driver_test.go b/drivers/i2c/ssd1306_driver_test.go index 420446a4b..c5869bff8 100644 --- a/drivers/i2c/ssd1306_driver_test.go +++ b/drivers/i2c/ssd1306_driver_test.go @@ -1,24 +1,27 @@ package i2c import ( - "errors" "fmt" "image" "reflect" "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver // and tests all implementations, so no further tests needed here for gobot.Driver interface var _ gobot.Driver = (*SSD1306Driver)(nil) -func initTestSSD1306DriverWithStubbedAdaptor(width, height int, externalVCC bool) (*SSD1306Driver, *i2cTestAdaptor) { +func initTestSSD1306DriverWithStubbedAdaptor( + width, height int, + externalVCC bool, //nolint:unparam // keep for tests +) (*SSD1306Driver, *i2cTestAdaptor) { a := newI2cTestAdaptor() - d := NewSSD1306Driver(a, WithSSD1306DisplayWidth(width), WithSSD1306DisplayHeight(height), WithSSD1306ExternalVCC(externalVCC)) + d := NewSSD1306Driver(a, WithSSD1306DisplayWidth(width), WithSSD1306DisplayHeight(height), + WithSSD1306ExternalVCC(externalVCC)) if err := d.Start(); err != nil { panic(err) } @@ -31,9 +34,9 @@ func TestNewSSD1306Driver(t *testing.T) { if !ok { t.Errorf("new should have returned a *SSD1306Driver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "SSD1306"), true) - gobottest.Assert(t, d.defaultAddress, 0x3c) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "SSD1306")) + assert.Equal(t, 0x3c, d.defaultAddress) } func TestSSD1306StartDefault(t *testing.T) { @@ -44,7 +47,7 @@ func TestSSD1306StartDefault(t *testing.T) { ) d := NewSSD1306Driver(newI2cTestAdaptor(), WithSSD1306DisplayWidth(width), WithSSD1306DisplayHeight(height), WithSSD1306ExternalVCC(externalVCC)) - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestSSD1306Start128x32(t *testing.T) { @@ -55,7 +58,7 @@ func TestSSD1306Start128x32(t *testing.T) { ) d := NewSSD1306Driver(newI2cTestAdaptor(), WithSSD1306DisplayWidth(width), WithSSD1306DisplayHeight(height), WithSSD1306ExternalVCC(externalVCC)) - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestSSD1306Start96x16(t *testing.T) { @@ -66,7 +69,7 @@ func TestSSD1306Start96x16(t *testing.T) { ) d := NewSSD1306Driver(newI2cTestAdaptor(), WithSSD1306DisplayWidth(width), WithSSD1306DisplayHeight(height), WithSSD1306ExternalVCC(externalVCC)) - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestSSD1306StartExternalVCC(t *testing.T) { @@ -77,7 +80,7 @@ func TestSSD1306StartExternalVCC(t *testing.T) { ) d := NewSSD1306Driver(newI2cTestAdaptor(), WithSSD1306DisplayWidth(width), WithSSD1306DisplayHeight(height), WithSSD1306ExternalVCC(externalVCC)) - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestSSD1306StartSizeError(t *testing.T) { @@ -88,35 +91,35 @@ func TestSSD1306StartSizeError(t *testing.T) { ) d := NewSSD1306Driver(newI2cTestAdaptor(), WithSSD1306DisplayWidth(width), WithSSD1306DisplayHeight(height), WithSSD1306ExternalVCC(externalVCC)) - gobottest.Assert(t, d.Start(), errors.New("128x54 resolution is unsupported, supported resolutions: 128x64, 128x32, 96x16")) + assert.ErrorContains(t, d.Start(), "128x54 resolution is unsupported, supported resolutions: 128x64, 128x32, 96x16") } func TestSSD1306Halt(t *testing.T) { s, _ := initTestSSD1306DriverWithStubbedAdaptor(128, 64, false) - gobottest.Assert(t, s.Halt(), nil) + assert.NoError(t, s.Halt()) } func TestSSD1306Options(t *testing.T) { s := NewSSD1306Driver(newI2cTestAdaptor(), WithBus(2), WithSSD1306DisplayHeight(32), WithSSD1306DisplayWidth(128)) - gobottest.Assert(t, s.GetBusOrDefault(1), 2) - gobottest.Assert(t, s.displayHeight, 32) - gobottest.Assert(t, s.displayWidth, 128) + assert.Equal(t, 2, s.GetBusOrDefault(1)) + assert.Equal(t, 32, s.displayHeight) + assert.Equal(t, 128, s.displayWidth) } func TestSSD1306Display(t *testing.T) { s, _ := initTestSSD1306DriverWithStubbedAdaptor(96, 16, false) _ = s.Start() - gobottest.Assert(t, s.Display(), nil) + assert.NoError(t, s.Display()) } func TestSSD1306ShowImage(t *testing.T) { s, _ := initTestSSD1306DriverWithStubbedAdaptor(128, 64, false) _ = s.Start() img := image.NewRGBA(image.Rect(0, 0, 640, 480)) - gobottest.Assert(t, s.ShowImage(img), errors.New("image must match display width and height: 128x64")) + assert.ErrorContains(t, s.ShowImage(img), "image must match display width and height: 128x64") img = image.NewRGBA(image.Rect(0, 0, 128, 64)) - gobottest.Assert(t, s.ShowImage(img), nil) + assert.NoError(t, s.ShowImage(img)) } func TestSSD1306Command(t *testing.T) { @@ -132,7 +135,7 @@ func TestSSD1306Command(t *testing.T) { return 0, nil } err := s.command(0xFF) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) } func TestSSD1306Commands(t *testing.T) { @@ -148,7 +151,7 @@ func TestSSD1306Commands(t *testing.T) { return 0, nil } err := s.commands([]byte{0x00, 0xFF}) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) } func TestSSD1306On(t *testing.T) { @@ -164,7 +167,7 @@ func TestSSD1306On(t *testing.T) { return 0, nil } err := s.On() - gobottest.Assert(t, err, nil) + assert.NoError(t, err) } func TestSSD1306Off(t *testing.T) { @@ -180,7 +183,7 @@ func TestSSD1306Off(t *testing.T) { return 0, nil } err := s.Off() - gobottest.Assert(t, err, nil) + assert.NoError(t, err) } func TestSSD1306Reset(t *testing.T) { @@ -197,7 +200,7 @@ func TestSSD1306Reset(t *testing.T) { return 0, nil } err := s.Reset() - gobottest.Assert(t, err, nil) + assert.NoError(t, err) } // COMMANDS @@ -205,28 +208,28 @@ func TestSSD1306Reset(t *testing.T) { func TestSSD1306CommandsDisplay(t *testing.T) { s, _ := initTestSSD1306DriverWithStubbedAdaptor(128, 64, false) result := s.Command("Display")(map[string]interface{}{}) - gobottest.Assert(t, result.(map[string]interface{})["err"], nil) + assert.Nil(t, result.(map[string]interface{})["err"]) } func TestSSD1306CommandsOn(t *testing.T) { s, _ := initTestSSD1306DriverWithStubbedAdaptor(128, 64, false) result := s.Command("On")(map[string]interface{}{}) - gobottest.Assert(t, result.(map[string]interface{})["err"], nil) + assert.Nil(t, result.(map[string]interface{})["err"]) } func TestSSD1306CommandsOff(t *testing.T) { s, _ := initTestSSD1306DriverWithStubbedAdaptor(128, 64, false) result := s.Command("Off")(map[string]interface{}{}) - gobottest.Assert(t, result.(map[string]interface{})["err"], nil) + assert.Nil(t, result.(map[string]interface{})["err"]) } func TestSSD1306CommandsClear(t *testing.T) { s, _ := initTestSSD1306DriverWithStubbedAdaptor(128, 64, false) result := s.Command("Clear")(map[string]interface{}{}) - gobottest.Assert(t, result.(map[string]interface{})["err"], nil) + assert.Nil(t, result.(map[string]interface{})["err"]) } func TestSSD1306CommandsSetContrast(t *testing.T) { @@ -243,19 +246,19 @@ func TestSSD1306CommandsSetContrast(t *testing.T) { result := s.Command("SetContrast")(map[string]interface{}{ "contrast": byte(0x10), }) - gobottest.Assert(t, result.(map[string]interface{})["err"], nil) + assert.Nil(t, result.(map[string]interface{})["err"]) } func TestSSD1306CommandsSet(t *testing.T) { s, _ := initTestSSD1306DriverWithStubbedAdaptor(128, 64, false) - gobottest.Assert(t, s.buffer.buffer[0], byte(0)) + assert.Equal(t, byte(0), s.buffer.buffer[0]) s.Command("Set")(map[string]interface{}{ "x": int(0), "y": int(0), "c": int(1), }) - gobottest.Assert(t, s.buffer.buffer[0], byte(1)) + assert.Equal(t, byte(1), s.buffer.buffer[0]) } func TestDisplayBuffer(t *testing.T) { @@ -273,17 +276,17 @@ func TestDisplayBuffer(t *testing.T) { len(display.buffer), size) } - gobottest.Assert(t, display.buffer[0], byte(0)) - gobottest.Assert(t, display.buffer[1], byte(0)) + assert.Equal(t, byte(0), display.buffer[0]) + assert.Equal(t, byte(0), display.buffer[1]) display.SetPixel(0, 0, 1) display.SetPixel(1, 0, 1) display.SetPixel(2, 0, 1) display.SetPixel(0, 1, 1) - gobottest.Assert(t, display.buffer[0], byte(3)) - gobottest.Assert(t, display.buffer[1], byte(1)) + assert.Equal(t, byte(3), display.buffer[0]) + assert.Equal(t, byte(1), display.buffer[1]) display.SetPixel(0, 1, 0) - gobottest.Assert(t, display.buffer[0], byte(1)) - gobottest.Assert(t, display.buffer[1], byte(1)) + assert.Equal(t, byte(1), display.buffer[0]) + assert.Equal(t, byte(1), display.buffer[1]) } diff --git a/drivers/i2c/th02_driver.go b/drivers/i2c/th02_driver.go index 4edee7900..bf29309e7 100644 --- a/drivers/i2c/th02_driver.go +++ b/drivers/i2c/th02_driver.go @@ -40,7 +40,7 @@ const ( th02Reg_Config = 0x03 th02Reg_ID = 0x11 - //th02Status_ReadyBit = 0x01 // D0 is /RDY + // th02Status_ReadyBit = 0x01 // D0 is /RDY th02Config_StartBit = 0x01 // D0 is START th02Config_HeatBit = 0x02 // D1 is HEAT @@ -50,8 +50,8 @@ const ( // Accuracy constants for the TH02 devices (deprecated, use WithFastMode() instead) const ( - TH02HighAccuracy = 0 //High Accuracy (T: 14 bit, H: 12 bit), normal (35 ms) - TH02LowAccuracy = 1 //Lower Accuracy (T: 13 bit, H: 11 bit), fast (18 ms) + TH02HighAccuracy = 0 // High Accuracy (T: 14 bit, H: 12 bit), normal (35 ms) + TH02LowAccuracy = 1 // Lower Accuracy (T: 13 bit, H: 11 bit), fast (18 ms) ) // TH02Driver is a Driver for a TH02 humidity and temperature sensor @@ -123,7 +123,7 @@ func (s *TH02Driver) SerialNumber() (uint8, error) { defer s.mutex.Unlock() ret, err := s.connection.ReadByteData(th02Reg_ID) - return uint8(ret) >> 4, err + return ret >> 4, err } // FastMode returns true if the fast mode is enabled in the device @@ -185,7 +185,6 @@ func (s *TH02Driver) Sample() (temperature float32, relhumidity float32, _ error } return temperature, relhumidity, nil - } func (s *TH02Driver) createConfig(measurement bool, readTemp bool) byte { diff --git a/drivers/i2c/th02_driver_test.go b/drivers/i2c/th02_driver_test.go index 1276424c9..26e9b3ce5 100644 --- a/drivers/i2c/th02_driver_test.go +++ b/drivers/i2c/th02_driver_test.go @@ -6,8 +6,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -29,17 +29,17 @@ func TestNewTH02Driver(t *testing.T) { if !ok { t.Errorf("NewTH02Driver() should have returned a *NewTH02Driver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "TH02"), true) - gobottest.Assert(t, d.defaultAddress, 0x40) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "TH02")) + assert.Equal(t, 0x40, d.defaultAddress) } func TestTH02Options(t *testing.T) { // This is a general test, that options are applied in constructor by using the common options. // Further tests for options can also be done by call of "WithOption(val)(d)". d := NewTH02Driver(newI2cTestAdaptor(), WithBus(2), WithAddress(0x42)) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) - gobottest.Assert(t, d.GetAddressOrDefault(0x33), 0x42) + assert.Equal(t, 2, d.GetBusOrDefault(1)) + assert.Equal(t, 0x42, d.GetAddressOrDefault(0x33)) } func TestTH02SetAccuracy(t *testing.T) { @@ -59,7 +59,7 @@ func TestTH02SetAccuracy(t *testing.T) { } func TestTH02WithFastMode(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { value int want bool }{ @@ -74,7 +74,7 @@ func TestTH02WithFastMode(t *testing.T) { // act WithTH02FastMode(tc.value)(d) // assert - gobottest.Assert(t, d.fastMode, tc.want) + assert.Equal(t, tc.want, d.fastMode) }) } } @@ -84,7 +84,7 @@ func TestTH02FastMode(t *testing.T) { // * write config register address (0x03) // * read register content // * if sixth bit (D5) is set, the fast mode is configured on, otherwise off - var tests = map[string]struct { + tests := map[string]struct { read uint8 want bool }{ @@ -102,10 +102,10 @@ func TestTH02FastMode(t *testing.T) { // act got, err := d.FastMode() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], uint8(0x03)) - gobottest.Assert(t, got, tc.want) + assert.NoError(t, err) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, uint8(0x03), a.written[0]) + assert.Equal(t, tc.want, got) }) } } @@ -116,7 +116,7 @@ func TestTH02SetHeater(t *testing.T) { // * write config register address (0x03) // * prepare config value by set/reset the heater bit (0x02, D1) // * write the config value - var tests = map[string]struct { + tests := map[string]struct { heater bool want uint8 }{ @@ -130,11 +130,11 @@ func TestTH02SetHeater(t *testing.T) { // act err := d.SetHeater(tc.heater) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, d.heating, tc.heater) - gobottest.Assert(t, len(a.written), 2) - gobottest.Assert(t, a.written[0], uint8(0x03)) - gobottest.Assert(t, a.written[1], tc.want) + assert.NoError(t, err) + assert.Equal(t, tc.heater, d.heating) + assert.Equal(t, 2, len(a.written)) + assert.Equal(t, uint8(0x03), a.written[0]) + assert.Equal(t, tc.want, a.written[1]) }) } } @@ -144,7 +144,7 @@ func TestTH02Heater(t *testing.T) { // * write config register address (0x03) // * read register content // * if second bit (D1) is set, the heater is configured on, otherwise off - var tests = map[string]struct { + tests := map[string]struct { read uint8 want bool }{ @@ -162,10 +162,10 @@ func TestTH02Heater(t *testing.T) { // act got, err := d.Heater() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], uint8(0x03)) - gobottest.Assert(t, got, tc.want) + assert.NoError(t, err) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, uint8(0x03), a.written[0]) + assert.Equal(t, tc.want, got) }) } } @@ -186,10 +186,10 @@ func TestTH02SerialNumber(t *testing.T) { // act sn, err := d.SerialNumber() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.written), 1) - gobottest.Assert(t, a.written[0], uint8(0x11)) - gobottest.Assert(t, sn, want) + assert.NoError(t, err) + assert.Equal(t, 1, len(a.written)) + assert.Equal(t, uint8(0x11), a.written[0]) + assert.Equal(t, want, sn) } func TestTH02Sample(t *testing.T) { @@ -207,7 +207,7 @@ func TestTH02Sample(t *testing.T) { // test table according to data sheet page 15, 17 // operating range of the temperature sensor is -40..85 °C (F-grade 0..70 °C) - var tests = map[string]struct { + tests := map[string]struct { hData uint16 tData uint16 wantRH float32 @@ -289,7 +289,7 @@ func TestTH02Sample(t *testing.T) { b[0] = byte(data >> 8) // first read MSB from register 0x01 b[1] = byte(data & 0xFF) // second read LSB from register 0x02 default: - gobottest.Assert(t, fmt.Sprintf("unexpected register %d", reg), "only register 0 and 1 expected") + assert.Equal(t, "only register 0 and 1 expected", fmt.Sprintf("unexpected register %d", reg)) return 0, nil } return len(b), nil @@ -297,9 +297,9 @@ func TestTH02Sample(t *testing.T) { // act temp, rh, err := d.Sample() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, rh, float32(tc.wantRH)) - gobottest.Assert(t, temp, float32(tc.wantT)) + assert.NoError(t, err) + assert.Equal(t, tc.wantRH, rh) + assert.Equal(t, tc.wantT, temp) }) } } @@ -309,7 +309,7 @@ func TestTH02_readData(t *testing.T) { var callCounter int - var tests = map[string]struct { + tests := map[string]struct { rd func([]byte) (int, error) wr func([]byte) (int, error) rtn uint16 @@ -415,8 +415,8 @@ func TestTH02_readData(t *testing.T) { // act got, err := d.waitAndReadData() // assert - gobottest.Assert(t, err, tc.wantErr) - gobottest.Assert(t, got, tc.rtn) + assert.Equal(t, tc.wantErr, err) + assert.Equal(t, tc.rtn, got) }) } } @@ -455,7 +455,7 @@ func TestTH02_waitForReadyFailOnReadError(t *testing.T) { func TestTH02_createConfig(t *testing.T) { d := &TH02Driver{} - var tests = map[string]struct { + tests := map[string]struct { meas bool fast bool readTemp bool @@ -485,7 +485,7 @@ func TestTH02_createConfig(t *testing.T) { d.fastMode = tc.fast d.heating = tc.heating got := d.createConfig(tc.meas, tc.readTemp) - gobottest.Assert(t, tc.want, got) + assert.Equal(t, got, tc.want) }) } } diff --git a/drivers/i2c/tsl2561_driver.go b/drivers/i2c/tsl2561_driver.go index 7bc4fa8b6..cc3ff7160 100644 --- a/drivers/i2c/tsl2561_driver.go +++ b/drivers/i2c/tsl2561_driver.go @@ -121,18 +121,19 @@ type TSL2561Driver struct { // NewTSL2561Driver creates a new driver for the TSL2561 device. // // Params: -// c Connector - the Adaptor to use with this Driver +// +// c Connector - the Adaptor to use with this Driver // // Optional params: -// i2c.WithBus(int): bus to use with this driver -// i2c.WithAddress(int): address to use with this driver -// i2c.WithTSL2561Gain1X: sets the gain to 1X -// i2c.WithTSL2561Gain16X: sets the gain to 16X -// i2c.WithTSL2561AutoGain: turns on auto gain -// i2c.WithTSL2561IntegrationTime13MS: sets integration time to 13ms -// i2c.WithTSL2561IntegrationTime101MS: sets integration time to 101ms -// i2c.WithTSL2561IntegrationTime402MS: sets integration time to 402ms // +// i2c.WithBus(int): bus to use with this driver +// i2c.WithAddress(int): address to use with this driver +// i2c.WithTSL2561Gain1X: sets the gain to 1X +// i2c.WithTSL2561Gain16X: sets the gain to 16X +// i2c.WithTSL2561AutoGain: turns on auto gain +// i2c.WithTSL2561IntegrationTime13MS: sets integration time to 13ms +// i2c.WithTSL2561IntegrationTime101MS: sets integration time to 101ms +// i2c.WithTSL2561IntegrationTime402MS: sets integration time to 402ms func NewTSL2561Driver(c Connector, options ...func(Config)) *TSL2561Driver { d := &TSL2561Driver{ Driver: NewDriver(c, "TSL2561", TSL2561AddressFloat), @@ -282,7 +283,7 @@ func (d *TSL2561Driver) GetLuminocity() (broadband uint16, ir uint16, err error) } else { // If we've already adjusted the gain once, just return the new results. // This avoids endless loops where a value is at one extreme pre-gain, - // and the the other extreme post-gain + // and the other extreme post-gain valid = true } diff --git a/drivers/i2c/tsl2561_driver_test.go b/drivers/i2c/tsl2561_driver_test.go index 276c484fd..3609721a0 100644 --- a/drivers/i2c/tsl2561_driver_test.go +++ b/drivers/i2c/tsl2561_driver_test.go @@ -7,8 +7,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver @@ -39,20 +39,20 @@ func TestNewTSL2561Driver(t *testing.T) { if !ok { t.Errorf("NewTSL2561Driver() should have returned a *TSL2561Driver") } - gobottest.Refute(t, d.Driver, nil) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "TSL2561"), true) - gobottest.Assert(t, d.defaultAddress, 0x39) - gobottest.Assert(t, d.autoGain, false) - gobottest.Assert(t, d.gain, TSL2561Gain(0)) - gobottest.Assert(t, d.integrationTime, TSL2561IntegrationTime(2)) + assert.NotNil(t, d.Driver) + assert.True(t, strings.HasPrefix(d.Name(), "TSL2561")) + assert.Equal(t, 0x39, d.defaultAddress) + assert.False(t, d.autoGain) + assert.Equal(t, TSL2561Gain(0), d.gain) + assert.Equal(t, TSL2561IntegrationTime(2), d.integrationTime) } func TestTSL2561DriverOptions(t *testing.T) { // This is a general test, that options are applied in constructor by using the common WithBus() option and // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". d := NewTSL2561Driver(newI2cTestAdaptor(), WithBus(2), WithTSL2561AutoGain) - gobottest.Assert(t, d.GetBusOrDefault(1), 2) - gobottest.Assert(t, d.autoGain, true) + assert.Equal(t, 2, d.GetBusOrDefault(1)) + assert.True(t, d.autoGain) } func TestTSL2561DriverStart(t *testing.T) { @@ -60,7 +60,7 @@ func TestTSL2561DriverStart(t *testing.T) { d := NewTSL2561Driver(a) a.i2cReadImpl = testIDReader - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestTSL2561DriverStartNotFound(t *testing.T) { @@ -72,12 +72,12 @@ func TestTSL2561DriverStartNotFound(t *testing.T) { copy(b, buf.Bytes()) return buf.Len(), nil } - gobottest.Assert(t, d.Start(), errors.New("TSL2561 device not found (0x1)")) + assert.ErrorContains(t, d.Start(), "TSL2561 device not found (0x1)") } func TestTSL2561DriverHalt(t *testing.T) { d, _ := initTestTSL2561Driver() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestTSL2561DriverRead16(t *testing.T) { @@ -93,8 +93,8 @@ func TestTSL2561DriverRead16(t *testing.T) { return buf.Len(), nil } val, err := d.connection.ReadWordData(1) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, val, uint16(0xAEEA)) + assert.NoError(t, err) + assert.Equal(t, uint16(0xAEEA), val) } func TestTSL2561DriverValidOptions(t *testing.T) { @@ -105,9 +105,9 @@ func TestTSL2561DriverValidOptions(t *testing.T) { WithAddress(TSL2561AddressLow), WithTSL2561AutoGain) - gobottest.Refute(t, d, nil) - gobottest.Assert(t, d.autoGain, true) - gobottest.Assert(t, d.integrationTime, TSL2561IntegrationTime101MS) + assert.NotNil(t, d) + assert.True(t, d.autoGain) + assert.Equal(t, TSL2561IntegrationTime101MS, d.integrationTime) } func TestTSL2561DriverMoreOptions(t *testing.T) { @@ -118,9 +118,9 @@ func TestTSL2561DriverMoreOptions(t *testing.T) { WithAddress(TSL2561AddressLow), WithTSL2561Gain16X) - gobottest.Refute(t, d, nil) - gobottest.Assert(t, d.autoGain, false) - gobottest.Assert(t, d.gain, TSL2561Gain(TSL2561Gain16X)) + assert.NotNil(t, d) + assert.False(t, d.autoGain) + assert.Equal(t, TSL2561Gain(TSL2561Gain16X), d.gain) } func TestTSL2561DriverEvenMoreOptions(t *testing.T) { @@ -131,10 +131,10 @@ func TestTSL2561DriverEvenMoreOptions(t *testing.T) { WithAddress(TSL2561AddressLow), WithTSL2561Gain1X) - gobottest.Refute(t, d, nil) - gobottest.Assert(t, d.autoGain, false) - gobottest.Assert(t, d.gain, TSL2561Gain(TSL2561Gain1X)) - gobottest.Assert(t, d.integrationTime, TSL2561IntegrationTime13MS) + assert.NotNil(t, d) + assert.False(t, d.autoGain) + assert.Equal(t, TSL2561Gain1X, d.gain) + assert.Equal(t, TSL2561IntegrationTime13MS, d.integrationTime) } func TestTSL2561DriverYetEvenMoreOptions(t *testing.T) { @@ -145,9 +145,9 @@ func TestTSL2561DriverYetEvenMoreOptions(t *testing.T) { WithAddress(TSL2561AddressLow), WithTSL2561AutoGain) - gobottest.Refute(t, d, nil) - gobottest.Assert(t, d.autoGain, true) - gobottest.Assert(t, d.integrationTime, TSL2561IntegrationTime402MS) + assert.NotNil(t, d) + assert.True(t, d.autoGain) + assert.Equal(t, TSL2561IntegrationTime402MS, d.integrationTime) } func TestTSL2561DriverGetDataWriteError(t *testing.T) { @@ -157,7 +157,7 @@ func TestTSL2561DriverGetDataWriteError(t *testing.T) { } _, _, err := d.getData() - gobottest.Assert(t, err, errors.New("write error")) + assert.ErrorContains(t, err, "write error") } func TestTSL2561DriverGetDataReadError(t *testing.T) { @@ -167,7 +167,7 @@ func TestTSL2561DriverGetDataReadError(t *testing.T) { } _, _, err := d.getData() - gobottest.Assert(t, err, errors.New("read error")) + assert.ErrorContains(t, err, "read error") } func TestTSL2561DriverGetLuminocity(t *testing.T) { @@ -180,10 +180,10 @@ func TestTSL2561DriverGetLuminocity(t *testing.T) { return buf.Len(), nil } bb, ir, err := d.GetLuminocity() - gobottest.Assert(t, err, nil) - gobottest.Assert(t, bb, uint16(12365)) - gobottest.Assert(t, ir, uint16(12365)) - gobottest.Assert(t, d.CalculateLux(bb, ir), uint32(72)) + assert.NoError(t, err) + assert.Equal(t, uint16(12365), bb) + assert.Equal(t, uint16(12365), ir) + assert.Equal(t, uint32(72), d.CalculateLux(bb, ir)) } func TestTSL2561DriverGetLuminocityAutoGain(t *testing.T) { @@ -202,10 +202,10 @@ func TestTSL2561DriverGetLuminocityAutoGain(t *testing.T) { _ = d.Start() bb, ir, err := d.GetLuminocity() - gobottest.Assert(t, err, nil) - gobottest.Assert(t, bb, uint16(12365)) - gobottest.Assert(t, ir, uint16(12365)) - gobottest.Assert(t, d.CalculateLux(bb, ir), uint32(72)) + assert.NoError(t, err) + assert.Equal(t, uint16(12365), bb) + assert.Equal(t, uint16(12365), ir) + assert.Equal(t, uint32(72), d.CalculateLux(bb, ir)) } func TestTSL2561SetIntegrationTimeError(t *testing.T) { @@ -213,7 +213,7 @@ func TestTSL2561SetIntegrationTimeError(t *testing.T) { a.i2cWriteImpl = func([]byte) (int, error) { return 0, errors.New("write error") } - gobottest.Assert(t, d.SetIntegrationTime(TSL2561IntegrationTime101MS), errors.New("write error")) + assert.ErrorContains(t, d.SetIntegrationTime(TSL2561IntegrationTime101MS), "write error") } func TestTSL2561SetGainError(t *testing.T) { @@ -221,7 +221,7 @@ func TestTSL2561SetGainError(t *testing.T) { a.i2cWriteImpl = func([]byte) (int, error) { return 0, errors.New("write error") } - gobottest.Assert(t, d.SetGain(TSL2561Gain16X), errors.New("write error")) + assert.ErrorContains(t, d.SetGain(TSL2561Gain16X), "write error") } func TestTSL2561getHiLo13MS(t *testing.T) { @@ -231,8 +231,8 @@ func TestTSL2561getHiLo13MS(t *testing.T) { WithTSL2561AutoGain) hi, lo := d.getHiLo() - gobottest.Assert(t, hi, uint16(tsl2561AgcTHi13MS)) - gobottest.Assert(t, lo, uint16(tsl2561AgcTLo13MS)) + assert.Equal(t, uint16(tsl2561AgcTHi13MS), hi) + assert.Equal(t, uint16(tsl2561AgcTLo13MS), lo) } func TestTSL2561getHiLo101MS(t *testing.T) { @@ -242,8 +242,8 @@ func TestTSL2561getHiLo101MS(t *testing.T) { WithTSL2561AutoGain) hi, lo := d.getHiLo() - gobottest.Assert(t, hi, uint16(tsl2561AgcTHi101MS)) - gobottest.Assert(t, lo, uint16(tsl2561AgcTLo101MS)) + assert.Equal(t, uint16(tsl2561AgcTHi101MS), hi) + assert.Equal(t, uint16(tsl2561AgcTLo101MS), lo) } func TestTSL2561getHiLo402MS(t *testing.T) { @@ -253,8 +253,8 @@ func TestTSL2561getHiLo402MS(t *testing.T) { WithTSL2561AutoGain) hi, lo := d.getHiLo() - gobottest.Assert(t, hi, uint16(tsl2561AgcTHi402MS)) - gobottest.Assert(t, lo, uint16(tsl2561AgcTLo402MS)) + assert.Equal(t, uint16(tsl2561AgcTHi402MS), hi) + assert.Equal(t, uint16(tsl2561AgcTLo402MS), lo) } func TestTSL2561getClipScaling13MS(t *testing.T) { @@ -265,8 +265,8 @@ func TestTSL2561getClipScaling13MS(t *testing.T) { c, s := d.getClipScaling() d.waitForADC() - gobottest.Assert(t, c, uint16(tsl2561Clipping13MS)) - gobottest.Assert(t, s, uint32(tsl2561LuxCHScaleTInt0)) + assert.Equal(t, uint16(tsl2561Clipping13MS), c) + assert.Equal(t, uint32(tsl2561LuxCHScaleTInt0), s) } func TestTSL2561getClipScaling101MS(t *testing.T) { @@ -277,8 +277,8 @@ func TestTSL2561getClipScaling101MS(t *testing.T) { c, s := d.getClipScaling() d.waitForADC() - gobottest.Assert(t, c, uint16(tsl2561Clipping101MS)) - gobottest.Assert(t, s, uint32(tsl2561LuxChScaleTInt1)) + assert.Equal(t, uint16(tsl2561Clipping101MS), c) + assert.Equal(t, uint32(tsl2561LuxChScaleTInt1), s) } func TestTSL2561getClipScaling402MS(t *testing.T) { @@ -289,8 +289,8 @@ func TestTSL2561getClipScaling402MS(t *testing.T) { c, s := d.getClipScaling() d.waitForADC() - gobottest.Assert(t, c, uint16(tsl2561Clipping402MS)) - gobottest.Assert(t, s, uint32(1<2 seconds the state changes func main() { - board := nanopi.NewNeoAdaptor() work := func() { diff --git a/examples/nanopi_pca9533.go b/examples/nanopi_pca9533.go index 9c5f64bb1..73a5d614a 100644 --- a/examples/nanopi_pca9533.go +++ b/examples/nanopi_pca9533.go @@ -129,5 +129,4 @@ func initialize(pca *i2c.PCA953xDriver, led2FrequHz float32, led3FrequHz float32 if err != nil { fmt.Println("errW:", err) } - } diff --git a/examples/raspi_adafruit_servo.go b/examples/raspi_adafruit2327_servo.go similarity index 90% rename from examples/raspi_adafruit_servo.go rename to examples/raspi_adafruit2327_servo.go index 1d56311b0..b34f1b6c4 100644 --- a/examples/raspi_adafruit_servo.go +++ b/examples/raspi_adafruit2327_servo.go @@ -15,7 +15,7 @@ import ( "gobot.io/x/gobot/v2/platforms/raspi" ) -var ( +const ( // Min pulse length out of 4096 servoMin = 150 // Max pulse length out of 4096 @@ -27,23 +27,36 @@ var ( yawDeg = 90 ) -func degree2pulse(deg int) int32 { - pulse := servoMin - pulse += ((servoMax - servoMin) / maxDegree) * deg - return int32(pulse) -} +func main() { + r := raspi.NewAdaptor() -func adafruitServoMotorRunner(a *i2c.AdafruitMotorHatDriver) (err error) { - log.Printf("Servo Motor Run Loop...\n") // Changing from the default 0x40 address because this configuration involves // a Servo HAT stacked on top of a DC/Stepper Motor HAT on top of the Pi. stackedHatAddr := 0x41 + + adaFruit := i2c.NewAdafruit2327Driver(r, i2c.WithAddress(stackedHatAddr)) + + work := func() { + gobot.Every(5*time.Second, func() { + adafruitServoMotorRunner(adaFruit) + }) + } + + robot := gobot.NewRobot("adaFruitBot", + []gobot.Connection{r}, + []gobot.Device{adaFruit}, + work, + ) + + robot.Start() +} + +func adafruitServoMotorRunner(a *i2c.Adafruit2327Driver) (err error) { + log.Printf("Servo Motor Run Loop...\n") + var channel byte = 1 deg := 90 - // update the I2C address state - a.SetServoHatAddress(stackedHatAddr) - // Do not need to set this every run loop freq := 60.0 if err = a.SetServoMotorFreq(freq); err != nil { @@ -72,21 +85,8 @@ func adafruitServoMotorRunner(a *i2c.AdafruitMotorHatDriver) (err error) { return } -func main() { - r := raspi.NewAdaptor() - adaFruit := i2c.NewAdafruitMotorHatDriver(r) - - work := func() { - gobot.Every(5*time.Second, func() { - adafruitServoMotorRunner(adaFruit) - }) - } - - robot := gobot.NewRobot("adaFruitBot", - []gobot.Connection{r}, - []gobot.Device{adaFruit}, - work, - ) - - robot.Start() +func degree2pulse(deg int) int32 { + pulse := servoMin + pulse += ((servoMax - servoMin) / maxDegree) * deg + return int32(pulse) } diff --git a/examples/raspi_adafruit_dcmotor.go b/examples/raspi_adafruit2348_dcmotor.go similarity index 64% rename from examples/raspi_adafruit_dcmotor.go rename to examples/raspi_adafruit2348_dcmotor.go index 8850a0bbc..c617d0b48 100644 --- a/examples/raspi_adafruit_dcmotor.go +++ b/examples/raspi_adafruit2348_dcmotor.go @@ -15,7 +15,29 @@ import ( "gobot.io/x/gobot/v2/platforms/raspi" ) -func adafruitDCMotorRunner(a *i2c.AdafruitMotorHatDriver, dcMotor int) (err error) { +func main() { + r := raspi.NewAdaptor() + + // we use the default address 0x60 for DC/Stepper Motor HAT on top of the Pi + adaFruit := i2c.NewAdafruit2348Driver(r) + + work := func() { + gobot.Every(5*time.Second, func() { + dcMotor := 2 // 0-based + adafruitDCMotorRunner(adaFruit, dcMotor) + }) + } + + robot := gobot.NewRobot("adaFruitBot", + []gobot.Connection{r}, + []gobot.Device{adaFruit}, + work, + ) + + robot.Start() +} + +func adafruitDCMotorRunner(a *i2c.Adafruit2348Driver, dcMotor int) (err error) { log.Printf("DC Motor Run Loop...\n") // set the speed: var speed int32 = 255 // 255 = full speed! @@ -23,43 +45,22 @@ func adafruitDCMotorRunner(a *i2c.AdafruitMotorHatDriver, dcMotor int) (err erro return } // run FORWARD - if err = a.RunDCMotor(dcMotor, i2c.AdafruitForward); err != nil { + if err = a.RunDCMotor(dcMotor, i2c.Adafruit2348Forward); err != nil { return } // Sleep and RELEASE time.Sleep(2000 * time.Millisecond) - if err = a.RunDCMotor(dcMotor, i2c.AdafruitRelease); err != nil { + if err = a.RunDCMotor(dcMotor, i2c.Adafruit2348Release); err != nil { return } // run BACKWARD - if err = a.RunDCMotor(dcMotor, i2c.AdafruitBackward); err != nil { + if err = a.RunDCMotor(dcMotor, i2c.Adafruit2348Backward); err != nil { return } // Sleep and RELEASE time.Sleep(2000 * time.Millisecond) - if err = a.RunDCMotor(dcMotor, i2c.AdafruitRelease); err != nil { + if err = a.RunDCMotor(dcMotor, i2c.Adafruit2348Release); err != nil { return } return } - -func main() { - r := raspi.NewAdaptor() - adaFruit := i2c.NewAdafruitMotorHatDriver(r) - - work := func() { - gobot.Every(5*time.Second, func() { - - dcMotor := 2 // 0-based - adafruitDCMotorRunner(adaFruit, dcMotor) - }) - } - - robot := gobot.NewRobot("adaFruitBot", - []gobot.Connection{r}, - []gobot.Device{adaFruit}, - work, - ) - - robot.Start() -} diff --git a/examples/raspi_adafruit_stepper.go b/examples/raspi_adafruit2348_stepper.go similarity index 65% rename from examples/raspi_adafruit_stepper.go rename to examples/raspi_adafruit2348_stepper.go index 205b1d265..cbac4bc6e 100644 --- a/examples/raspi_adafruit_stepper.go +++ b/examples/raspi_adafruit2348_stepper.go @@ -15,29 +15,11 @@ import ( "gobot.io/x/gobot/v2/platforms/raspi" ) -func adafruitStepperMotorRunner(a *i2c.AdafruitMotorHatDriver, motor int) (err error) { - log.Printf("Stepper Motor Run Loop...\n") - // set the speed state: - speed := 30 // rpm - style := i2c.AdafruitDouble - steps := 20 - - a.SetStepperMotorSpeed(motor, speed) - - if err = a.Step(motor, steps, i2c.AdafruitForward, style); err != nil { - log.Printf(err.Error()) - return - } - if err = a.Step(motor, steps, i2c.AdafruitBackward, style); err != nil { - log.Printf(err.Error()) - return - } - return -} - func main() { r := raspi.NewAdaptor() - adaFruit := i2c.NewAdafruitMotorHatDriver(r) + + // we use the default address 0x60 for DC/Stepper Motor HAT on top of the Pi + adaFruit := i2c.NewAdafruit2348Driver(r) work := func() { gobot.Every(5*time.Second, func() { @@ -54,3 +36,23 @@ func main() { robot.Start() } + +func adafruitStepperMotorRunner(a *i2c.Adafruit2348Driver, motor int) (err error) { + log.Printf("Stepper Motor Run Loop...\n") + // set the speed state: + speed := 30 // rpm + style := i2c.Adafruit2348Double + steps := 20 + + a.SetStepperMotorSpeed(motor, speed) + + if err = a.Step(motor, steps, i2c.Adafruit2348Forward, style); err != nil { + log.Printf(err.Error()) + return + } + if err = a.Step(motor, steps, i2c.Adafruit2348Backward, style); err != nil { + log.Printf(err.Error()) + return + } + return +} diff --git a/examples/raspi_direct_pin_event.go b/examples/raspi_direct_pin_event.go index ccb44c0a9..0f50f3122 100644 --- a/examples/raspi_direct_pin_event.go +++ b/examples/raspi_direct_pin_event.go @@ -34,7 +34,6 @@ var ( // LED's: the output pins are wired to the cathode of a LED, the anode is wired with a resistor (70-130Ohm for 20mA) to VCC // Expected behavior: always one LED is on, the other in opposite state, if button is pressed for >2 seconds the state changes func main() { - board := raspi.NewAdaptor() work := func() { diff --git a/examples/raspi_generic.go b/examples/raspi_generic.go index 45ea5cbe3..319986cdc 100644 --- a/examples/raspi_generic.go +++ b/examples/raspi_generic.go @@ -74,7 +74,6 @@ func main() { if read && write { if reflect.DeepEqual(wData, rData) { fmt.Printf("EEPROM addr: %d equal: %v\n", eepromAddr, rData) - } else { fmt.Printf("EEPROM addr: %d wr: %v differ rd: %v\n", eepromAddr, wData, rData) } diff --git a/examples/raspi_hcsr04.go b/examples/raspi_hcsr04.go new file mode 100644 index 000000000..83fd3d31e --- /dev/null +++ b/examples/raspi_hcsr04.go @@ -0,0 +1,89 @@ +//go:build example +// +build example + +// +// Do not build by default. + +package main + +import ( + "fmt" + "log" + "os" + "time" + + "gobot.io/x/gobot/v2" + "gobot.io/x/gobot/v2/drivers/gpio" + "gobot.io/x/gobot/v2/platforms/raspi" +) + +func main() { + const ( + triggerOutput = "11" + echoInput = "13" + ) + + // this is mandatory for systems with defunct edge detection, although the "cdev" is used with an newer Kernel + // keep in mind, that this cause more inaccurate measurements + const pollEdgeDetection = true + + a := raspi.NewAdaptor() + hcsr04 := gpio.NewHCSR04Driver(a, triggerOutput, echoInput, pollEdgeDetection) + + work := func() { + if pollEdgeDetection { + fmt.Println("Please note that measurements are CPU consuming and will be more inaccurate with this setting.") + fmt.Println("After startup the system is under load and the measurement is very inaccurate, so wait a bit...") + time.Sleep(2000 * time.Millisecond) + } + + if err := hcsr04.StartDistanceMonitor(); err != nil { + log.Fatal(err) + } + + // first single shot + if v, err := hcsr04.MeasureDistance(); err != nil { + log.Fatal(err) + } else { + fmt.Printf("first single shot done: %5.3f m\n", v) + } + + ticker := gobot.Every(1*time.Second, func() { + fmt.Printf("continuous measurement: %5.3f m\n", hcsr04.Distance()) + }) + + gobot.After(5*time.Second, func() { + if err := hcsr04.StopDistanceMonitor(); err != nil { + log.Fatal(err) + } + ticker.Stop() + }) + + gobot.After(7*time.Second, func() { + // second single shot + if v, err := hcsr04.MeasureDistance(); err != nil { + log.Fatal(err) + } else { + fmt.Printf("second single shot done: %5.3f m\n", v) + } + // cleanup + if err := hcsr04.Halt(); err != nil { + log.Println(err) + } + if err := a.Finalize(); err != nil { + log.Println(err) + } + os.Exit(0) + }) + } + + robot := gobot.NewRobot("distanceBot", + []gobot.Connection{a}, + []gobot.Device{hcsr04}, + work, + ) + + if err := robot.Start(); err != nil { + log.Fatal(err) + } +} diff --git a/examples/raspi_hmc5883l.go b/examples/raspi_hmc5883l.go index 57c55b430..1a6e46dc1 100644 --- a/examples/raspi_hmc5883l.go +++ b/examples/raspi_hmc5883l.go @@ -27,7 +27,6 @@ func main() { work := func() { gobot.Every(200*time.Millisecond, func() { - // get heading in radians, to convert to degrees multiply by 180/math.Pi heading, _ := hmc5883l.Heading() fmt.Println("Heading", heading) diff --git a/examples/raspi_ina3221.go b/examples/raspi_ina3221.go index 001f41532..13f4786bd 100644 --- a/examples/raspi_ina3221.go +++ b/examples/raspi_ina3221.go @@ -16,12 +16,10 @@ import ( ) func main() { - r := raspi.NewAdaptor() ina := i2c.NewINA3221Driver(r) work := func() { - gobot.Every(5*time.Second, func() { for _, ch := range []i2c.INA3221Channel{i2c.INA3221Channel1, i2c.INA3221Channel2, i2c.INA3221Channel3} { val, err := ina.GetBusVoltage(ch) diff --git a/examples/raspi_pca9533.go b/examples/raspi_pca9533.go index a48ec1f4d..f71959f2f 100644 --- a/examples/raspi_pca9533.go +++ b/examples/raspi_pca9533.go @@ -129,5 +129,4 @@ func initialize(pca *i2c.PCA953xDriver, led2FrequHz float32, led3FrequHz float32 if err != nil { fmt.Println("errW:", err) } - } diff --git a/examples/raspi_ssd1306.go b/examples/raspi_ssd1306.go index fc08aa938..c43f58175 100644 --- a/examples/raspi_ssd1306.go +++ b/examples/raspi_ssd1306.go @@ -23,7 +23,6 @@ func main() { stage := false work := func() { - gobot.Every(1*time.Second, func() { oled.Clear() if stage { diff --git a/examples/raspi_stepper_move.go b/examples/raspi_stepper_move.go index 5c22b9b2a..61784039c 100644 --- a/examples/raspi_stepper_move.go +++ b/examples/raspi_stepper_move.go @@ -19,15 +19,15 @@ func main() { stepper := gpio.NewStepperDriver(r, [4]string{"7", "11", "13", "15"}, gpio.StepperModes.DualPhaseStepping, 2048) work := func() { - //set spped + // set spped stepper.SetSpeed(15) - //Move forward one revolution + // Move forward one revolution if err := stepper.Move(2048); err != nil { fmt.Println(err) } - //Move backward one revolution + // Move backward one revolution if err := stepper.Move(-2048); err != nil { fmt.Println(err) } diff --git a/examples/sphero_calibration.go b/examples/sphero_calibration.go new file mode 100644 index 000000000..d48d0542b --- /dev/null +++ b/examples/sphero_calibration.go @@ -0,0 +1,67 @@ +//go:build example +// +build example + +// +// Do not build by default. + +package main + +import ( + "gobot.io/x/gobot/v2" + "gobot.io/x/gobot/v2/api" + "gobot.io/x/gobot/v2/platforms/keyboard" + "gobot.io/x/gobot/v2/platforms/sphero" +) + +func main() { + master := gobot.NewMaster() + a := api.NewAPI(master) + a.Start() + + ballConn := sphero.NewAdaptor("/dev/rfcomm0") + ball := sphero.NewSpheroDriver(ballConn) + + keys := keyboard.NewDriver() + + calibrating := false + + work := func() { + keys.On(keyboard.Key, func(data interface{}) { + key := data.(keyboard.KeyEvent) + + switch key.Key { + case keyboard.ArrowUp: + if calibrating { + break + } + ball.Roll(100, 0) + case keyboard.ArrowDown: + if calibrating { + break + } + ball.Roll(100, 100) + case keyboard.ArrowLeft: + ball.Roll(100, 270) + case keyboard.ArrowRight: + ball.Roll(100, 90) + case keyboard.Spacebar: + if calibrating { + ball.FinishCalibration() + } else { + ball.StartCalibration() + } + calibrating = !calibrating + } + }) + } + + robot := gobot.NewRobot("sphero-calibration", + []gobot.Connection{ballConn}, + []gobot.Device{ball, keys}, + work, + ) + + master.AddRobot(robot) + + master.Start() +} diff --git a/examples/tello_facetracker.go b/examples/tello_facetracker.go index 1a65dfd65..38cc2bcc6 100644 --- a/examples/tello_facetracker.go +++ b/examples/tello_facetracker.go @@ -74,7 +74,7 @@ var ( flightData *tello.FlightData // joystick - joyAdaptor = joystick.NewAdaptor() + joyAdaptor = joystick.NewAdaptor("0") stick = joystick.NewDriver(joyAdaptor, "dualshock4") leftX, leftY, rightX, rightY atomic.Value ) diff --git a/examples/tello_ps3.go b/examples/tello_ps3.go index 5d4f998d0..fb0e2a7f1 100644 --- a/examples/tello_ps3.go +++ b/examples/tello_ps3.go @@ -37,7 +37,7 @@ var leftX, leftY, rightX, rightY atomic.Value const offset = 32767.0 func main() { - joystickAdaptor := joystick.NewAdaptor() + joystickAdaptor := joystick.NewAdaptor("0") stick := joystick.NewDriver(joystickAdaptor, "dualshock3") drone := tello.NewDriver("8888") diff --git a/examples/tinkerboard_adafruit1109_lcd_keys.go b/examples/tinkerboard_adafruit1109_lcd_keys.go index ae3f93fe9..305c09484 100644 --- a/examples/tinkerboard_adafruit1109_lcd_keys.go +++ b/examples/tinkerboard_adafruit1109_lcd_keys.go @@ -110,9 +110,7 @@ func main() { } } }) - }) - } robot := gobot.NewRobot("adaBot", diff --git a/examples/tinkerboard_direct_pin.go b/examples/tinkerboard_direct_pin.go index 4a3b43522..222425f60 100644 --- a/examples/tinkerboard_direct_pin.go +++ b/examples/tinkerboard_direct_pin.go @@ -62,7 +62,6 @@ func main() { } else { level = 1 } - }) } diff --git a/examples/tinkerboard_generic.go b/examples/tinkerboard_generic.go index e54948b4d..c76e9e16e 100644 --- a/examples/tinkerboard_generic.go +++ b/examples/tinkerboard_generic.go @@ -84,7 +84,6 @@ func main() { if read && write { if reflect.DeepEqual(wData, rData) { fmt.Printf("EEPROM addr: %d equal: %v\n", eepromAddr, rData) - } else { fmt.Printf("EEPROM addr: %d wr: %v differ rd: %v\n", eepromAddr, wData, rData) } diff --git a/examples/tinkerboard_hcsr04.go b/examples/tinkerboard_hcsr04.go new file mode 100644 index 000000000..9c18140be --- /dev/null +++ b/examples/tinkerboard_hcsr04.go @@ -0,0 +1,93 @@ +//go:build example +// +build example + +// +// Do not build by default. + +package main + +import ( + "fmt" + "log" + "os" + "time" + + "gobot.io/x/gobot/v2" + "gobot.io/x/gobot/v2/drivers/gpio" + "gobot.io/x/gobot/v2/platforms/tinkerboard" +) + +// Wiring +// PWR Tinkerboard: 2(+5V), 6, 9, 14, 20 (GND) +// GPIO Tinkerboard: header pin 7 is the trigger output, pin 22 used as echo input +// HC-SR04: the power is wired to +5V and GND of tinkerboard, the same for trigger output and the echo input pin +func main() { + const ( + triggerOutput = "7" + echoInput = "22" + ) + + // this is mandatory for systems with defunct edge detection, although the "cdev" is used with an newer Kernel + // keep in mind, that this cause more inaccurate measurements + const pollEdgeDetection = true + + a := tinkerboard.NewAdaptor() + hcsr04 := gpio.NewHCSR04Driver(a, triggerOutput, echoInput, pollEdgeDetection) + + work := func() { + if pollEdgeDetection { + fmt.Println("Please note that measurements are CPU consuming and will be more inaccurate with this setting.") + fmt.Println("After startup the system is under load and the measurement is very inaccurate, so wait a bit...") + time.Sleep(2000 * time.Millisecond) + } + + if err := hcsr04.StartDistanceMonitor(); err != nil { + log.Fatal(err) + } + + // first single shot + if v, err := hcsr04.MeasureDistance(); err != nil { + log.Fatal(err) + } else { + fmt.Printf("first single shot done: %5.3f m\n", v) + } + + ticker := gobot.Every(1*time.Second, func() { + fmt.Printf("continuous measurement: %5.3f m\n", hcsr04.Distance()) + }) + + gobot.After(5*time.Second, func() { + if err := hcsr04.StopDistanceMonitor(); err != nil { + log.Fatal(err) + } + ticker.Stop() + }) + + gobot.After(7*time.Second, func() { + // second single shot + if v, err := hcsr04.MeasureDistance(); err != nil { + log.Fatal(err) + } else { + fmt.Printf("second single shot done: %5.3f m\n", v) + } + // cleanup + if err := hcsr04.Halt(); err != nil { + log.Println(err) + } + if err := a.Finalize(); err != nil { + log.Println(err) + } + os.Exit(0) + }) + } + + robot := gobot.NewRobot("distanceBot", + []gobot.Connection{a}, + []gobot.Device{hcsr04}, + work, + ) + + if err := robot.Start(); err != nil { + log.Fatal(err) + } +} diff --git a/examples/tinkerboard_mfcrc522gpio.go b/examples/tinkerboard_mfcrc522gpio.go index b630b2efe..fa126e2df 100644 --- a/examples/tinkerboard_mfcrc522gpio.go +++ b/examples/tinkerboard_mfcrc522gpio.go @@ -41,7 +41,6 @@ func main() { } gobot.Every(2*time.Second, func() { - if !wasCardDetected { fmt.Println("\n+++ poll for card +++") if err := d.IsCardPresent(); err != nil { @@ -64,7 +63,6 @@ func main() { fmt.Printf("-- start text --\n%s\n-- end text --\n", text) } } - }) } diff --git a/examples/tinkerboard_pca9533.go b/examples/tinkerboard_pca9533.go index 2b1360969..cf9b03085 100644 --- a/examples/tinkerboard_pca9533.go +++ b/examples/tinkerboard_pca9533.go @@ -129,5 +129,4 @@ func initialize(pca *i2c.PCA953xDriver, led2FrequHz float32, led3FrequHz float32 if err != nil { fmt.Println("errW:", err) } - } diff --git a/examples/tinkerboard_pcf8583_clock.go b/examples/tinkerboard_pcf8583_clock.go index da2e93dca..ddd3209be 100644 --- a/examples/tinkerboard_pcf8583_clock.go +++ b/examples/tinkerboard_pcf8583_clock.go @@ -25,7 +25,6 @@ func main() { pcf := i2c.NewPCF8583Driver(board, i2c.WithBus(1), i2c.WithPCF8583Mode(i2c.PCF8583CtrlModeClock50)) work := func() { - currentTime := time.Now() log.Println(currentTime) diff --git a/go.mod b/go.mod index 044643eea..74e58fe23 100644 --- a/go.mod +++ b/go.mod @@ -1,49 +1,48 @@ module gobot.io/x/gobot/v2 -go 1.18 +go 1.19 require ( + github.com/0xcafed00d/joystick v1.0.1 github.com/bmizerany/pat v0.0.0-20210406213842-e4b6760bdd6f github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0 - github.com/eclipse/paho.mqtt.golang v1.4.2 + github.com/eclipse/paho.mqtt.golang v1.4.3 github.com/gofrs/uuid v4.4.0+incompatible github.com/hashicorp/go-multierror v1.1.1 github.com/hybridgroup/go-ardrone v0.0.0-20140402002621-b9750d8d7b78 github.com/hybridgroup/mjpeg v0.0.0-20140228234708-4680f319790e - github.com/nats-io/nats.go v1.27.1 + github.com/nats-io/nats.go v1.31.0 + github.com/nsf/termbox-go v1.1.1 github.com/sigurn/crc8 v0.0.0-20220107193325-2243fe600f9f github.com/stretchr/testify v1.8.4 - github.com/veandco/go-sdl2 v0.4.35 - github.com/warthog618/gpiod v0.8.1 - go.bug.st/serial v1.5.0 - gocv.io/x/gocv v0.33.0 - golang.org/x/net v0.12.0 - golang.org/x/sys v0.10.0 + github.com/warthog618/gpiod v0.8.2 + go.bug.st/serial v1.6.1 + gocv.io/x/gocv v0.35.0 + golang.org/x/net v0.17.0 + golang.org/x/sys v0.13.0 periph.io/x/conn/v3 v3.7.0 periph.io/x/host/v3 v3.8.2 - tinygo.org/x/bluetooth v0.7.0 + tinygo.org/x/bluetooth v0.8.0 ) require ( github.com/creack/goselect v0.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/fatih/structs v1.1.0 // indirect - github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect - github.com/golang/protobuf v1.5.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/klauspost/compress v1.16.7 // indirect + github.com/klauspost/compress v1.17.1 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect github.com/muka/go-bluetooth v0.0.0-20221213043340-85dc80edc4e1 // indirect - github.com/nats-io/nats-server/v2 v2.7.4 // indirect - github.com/nats-io/nkeys v0.4.4 // indirect + github.com/nats-io/nkeys v0.4.5 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/saltosystems/winrt-go v0.0.0-20230613063811-c792451fa808 // indirect + github.com/saltosystems/winrt-go v0.0.0-20231011131235-9071442c0c84 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/tinygo-org/cbgo v0.0.4 // indirect - golang.org/x/crypto v0.11.0 // indirect - golang.org/x/sync v0.3.0 // indirect - google.golang.org/protobuf v1.28.1 // indirect + golang.org/x/crypto v0.14.0 // indirect + golang.org/x/sync v0.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index f590e4b61..1b2be75a9 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/bgould/http v0.0.0-20190627042742-d268792bdee7/go.mod h1:BTqvVegvwifopl4KTEDth6Zezs9eR+lCWhvGKvkxJHE= +github.com/0xcafed00d/joystick v1.0.1 h1:r4p2cRp4MHJWu1gArhGtumbkPxmr3tcOUTFqybEhplM= +github.com/0xcafed00d/joystick v1.0.1/go.mod h1:gzszjNgzP6jtCAeSdC9OqPVO5rO7TJuaw4P7eAjNzx8= github.com/bmizerany/pat v0.0.0-20210406213842-e4b6760bdd6f h1:gOO/tNZMjjvTKZWpY7YnXC72ULNLErRtp94LountVE8= github.com/bmizerany/pat v0.0.0-20210406213842-e4b6760bdd6f/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0= @@ -9,32 +9,20 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0 h1:C7t6eeMaEQVy6e8CarIhscYQlNmw5e3G36y7l7Y21Ao= github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0/go.mod h1:56wL82FO0bfMU5RvfXoIwSOP2ggqqxT+tAfNEIyxuHw= -github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= -github.com/eclipse/paho.mqtt.golang v1.4.2 h1:66wOzfUHSSI1zamx7jR6yMEI5EuHnT1G6rNA5PM12m4= -github.com/eclipse/paho.mqtt.golang v1.4.2/go.mod h1:JGt0RsEwEX+Xa/agj90YJ9d9DH2b7upDZMK9HRbFvCA= +github.com/eclipse/paho.mqtt.golang v1.4.3 h1:2kwcUGn8seMUfWndX0hGbvH8r7crgcJguQNCyp70xik= +github.com/eclipse/paho.mqtt.golang v1.4.3/go.mod h1:CSYvoAlsMkhYOXh/oKyxa8EcBci6dVkLCbo5tTC1RIE= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/frankban/quicktest v1.10.2/go.mod h1:K+q6oSqb0W0Ininfk863uOk1lMy69l/P6txr3mVT54s= -github.com/glerchundi/subcommands v0.0.0-20181212083838-923a6ccb11f8/go.mod h1:r0g3O7Y5lrWXgDfcFBRgnAKzjmPgTzwoMC2ieB345FY= -github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= -github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/hajimehoshi/go-jisx0208 v1.0.0/go.mod h1:yYxEStHL7lt9uL+AbdWgW9gBumwieDoZCiB1f/0X0as= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -44,133 +32,91 @@ github.com/hybridgroup/go-ardrone v0.0.0-20140402002621-b9750d8d7b78 h1:7of6LJZ4 github.com/hybridgroup/go-ardrone v0.0.0-20140402002621-b9750d8d7b78/go.mod h1:YllNbhGM1UEcySxCv1BWK5lre7QLmJJ+O0ADUOo2nbc= github.com/hybridgroup/mjpeg v0.0.0-20140228234708-4680f319790e h1:xCcwD5FOXul+j1dn8xD16nbrhJkkum/Cn+jTd/u1LhY= github.com/hybridgroup/mjpeg v0.0.0-20140228234708-4680f319790e/go.mod h1:eagM805MRKrioHYuU7iKLUyFPVKqVV6um5DAvCkUtXs= -github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.1 h1:NE3C767s2ak2bweCZo3+rdP4U/HoyVXLv/X9f2gPS5g= +github.com/klauspost/compress v1.17.1/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= -github.com/muka/go-bluetooth v0.0.0-20220830075246-0746e3a1ea53/go.mod h1:dMCjicU6vRBk34dqOmIZm0aod6gUwZXOXzBROqGous0= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/muka/go-bluetooth v0.0.0-20221213043340-85dc80edc4e1 h1:BuVRHr4HHJbk1DHyWkArJ7E8J/VA8ncCr/VLnQFazBo= github.com/muka/go-bluetooth v0.0.0-20221213043340-85dc80edc4e1/go.mod h1:dMCjicU6vRBk34dqOmIZm0aod6gUwZXOXzBROqGous0= -github.com/nats-io/jwt/v2 v2.2.1-0.20220113022732-58e87895b296 h1:vU9tpM3apjYlLLeY23zRWJ9Zktr5jp+mloR942LEOpY= -github.com/nats-io/nats-server/v2 v2.7.4 h1:c+BZJ3rGzUKCBIM4IXO8uNT2u1vajGbD1kPA6wqCEaM= -github.com/nats-io/nats-server/v2 v2.7.4/go.mod h1:1vZ2Nijh8tcyNe8BDVyTviCd9NYzRbubQYiEHsvOQWc= -github.com/nats-io/nats.go v1.27.1 h1:OuYnal9aKVSnOzLQIzf7554OXMCG7KbaTkCSBHRcSoo= -github.com/nats-io/nats.go v1.27.1/go.mod h1:XpbWUlOElGwTYbMR7imivs7jJj9GtK7ypv321Wp6pjc= -github.com/nats-io/nkeys v0.4.4 h1:xvBJ8d69TznjcQl9t6//Q5xXuVhyYiSos6RPtvQNTwA= -github.com/nats-io/nkeys v0.4.4/go.mod h1:XUkxdLPTufzlihbamfzQ7mw/VGx6ObUs+0bN5sNvt64= +github.com/nats-io/nats.go v1.31.0 h1:/WFBHEc/dOKBF6qf1TZhrdEfTmOZ5JzdJ+Y3m6Y/p7E= +github.com/nats-io/nats.go v1.31.0/go.mod h1:di3Bm5MLsoB4Bx61CBTsxuarI36WbhAwOm8QrW39+i8= +github.com/nats-io/nkeys v0.4.5 h1:Zdz2BUlFm4fJlierwvGK+yl20IAKUm7eV6AAZXEhkPk= +github.com/nats-io/nkeys v0.4.5/go.mod h1:XUkxdLPTufzlihbamfzQ7mw/VGx6ObUs+0bN5sNvt64= github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nsf/termbox-go v1.1.1 h1:nksUPLCb73Q++DwbYUBEglYBRPZyoXJdrj5L+TkjyZY= +github.com/nsf/termbox-go v1.1.1/go.mod h1:T0cTdVuOwf7pHQNtfhnEbzHbcNyCEcVU4YPpouCbVxo= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/paypal/gatt v0.0.0-20151011220935-4ae819d591cf/go.mod h1:+AwQL2mK3Pd3S+TUwg0tYQjid0q1txyNUJuuSmz8Kdk= -github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= -github.com/peterbourgon/ff/v3 v3.1.2/go.mod h1:XNJLY8EIl6MjMVjBS4F0+G0LYoAqs0DTa4rmHHukKDE= -github.com/pilebones/go-udev v0.9.0 h1:N1uEO/SxUwtIctc0WLU0t69JeBxIYEYnj8lT/Nabl9Q= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sago35/go-bdf v0.0.0-20200313142241-6c17821c91c4/go.mod h1:rOebXGuMLsXhZAC6mF/TjxONsm45498ZyzVhel++6KM= -github.com/saltosystems/winrt-go v0.0.0-20230510070731-e096b9afa761/go.mod h1:UvKm1lyhg+8ehk99i8g5Q7AX1LXUJgks0lRyAkG/ahQ= -github.com/saltosystems/winrt-go v0.0.0-20230613063811-c792451fa808 h1:OmW/lr7pviC5Fcsiz3qqc8dh0uo1r3EqqI/mDTSpGmc= -github.com/saltosystems/winrt-go v0.0.0-20230613063811-c792451fa808/go.mod h1:UvKm1lyhg+8ehk99i8g5Q7AX1LXUJgks0lRyAkG/ahQ= +github.com/saltosystems/winrt-go v0.0.0-20231011131235-9071442c0c84 h1:LX7qSkrsG8fKKVubiUnqfGdi/yBBnVTBR13LkqXycog= +github.com/saltosystems/winrt-go v0.0.0-20231011131235-9071442c0c84/go.mod h1:CIltaIm7qaANUIvzr0Vmz71lmQMAIbGJ7cvgzX7FMfA= github.com/sigurn/crc8 v0.0.0-20220107193325-2243fe600f9f h1:1R9KdKjCNSd7F8iGTxIpoID9prlYH8nuNYKt0XvweHA= github.com/sigurn/crc8 v0.0.0-20220107193325-2243fe600f9f/go.mod h1:vQhwQ4meQEDfahT5kd61wLAF5AAeh5ZPLVI4JJ/tYo8= github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/suapapa/go_eddystone v1.3.1/go.mod h1:bXC11TfJOS+3g3q/Uzd7FKd5g62STQEfeEIhcKe4Qy8= -github.com/tdakkota/win32metadata v0.1.0/go.mod h1:77e6YvX0LIVW+O81fhWLnXAxxcyu/wdZdG7iwed7Fyk= github.com/tinygo-org/cbgo v0.0.4 h1:3D76CRYbH03Rudi8sEgs/YO0x3JIMdyq8jlQtk/44fU= github.com/tinygo-org/cbgo v0.0.4/go.mod h1:7+HgWIHd4nbAz0ESjGlJ1/v9LDU1Ox8MGzP9mah/fLk= -github.com/valyala/fastjson v1.6.3/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= -github.com/veandco/go-sdl2 v0.4.35 h1:NohzsfageDWGtCd9nf7Pc3sokMK/MOK+UA2QMJARWzQ= -github.com/veandco/go-sdl2 v0.4.35/go.mod h1:OROqMhHD43nT4/i9crJukyVecjPNYYuCofep6SNiAjY= -github.com/warthog618/gpiod v0.8.1 h1:+8iHpHd3fljAd6l4AT8jPbMDQNKdvBIpW/hmLgAcHiM= -github.com/warthog618/gpiod v0.8.1/go.mod h1:A7v1hGR2eTsnkN+e9RoAPYgJG9bLJWtwyIIK+pgqC7s= +github.com/warthog618/go-gpiosim v0.1.0 h1:2rTMTcKUVZxpUuvRKsagnKAbKpd3Bwffp87xywEDVGI= +github.com/warthog618/gpiod v0.8.2 h1:2HgQ9pNowPp7W77sXhX5ut5Tqq1WoS3t7bXYDxtYvxc= +github.com/warthog618/gpiod v0.8.2/go.mod h1:O7BNpHjCn/4YS5yFVmoFZAlY1LuYuQ8vhPf0iy/qdi4= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.bug.st/serial v1.5.0 h1:ThuUkHpOEmCVXxGEfpoExjQCS2WBVV4ZcUKVYInM9T4= -go.bug.st/serial v1.5.0/go.mod h1:UABfsluHAiaNI+La2iESysd9Vetq7VRdpxvjx7CmmOE= -gocv.io/x/gocv v0.33.0 h1:WDtaBrq92AKrhepYzEktydDzNSm3t5k7ciawZK4rns8= -gocv.io/x/gocv v0.33.0/go.mod h1:oc6FvfYqfBp99p+yOEzs9tbYF9gOrAQSeL/dyIPefJU= +go.bug.st/serial v1.6.1 h1:VSSWmUxlj1T/YlRo2J104Zv3wJFrjHIl/T3NeruWAHY= +go.bug.st/serial v1.6.1/go.mod h1:UABfsluHAiaNI+La2iESysd9Vetq7VRdpxvjx7CmmOE= +gocv.io/x/gocv v0.35.0 h1:Qaxb5KdVyy8Spl4S4K0SMZ6CVmKtbfoSGQAxRD3FZlw= +gocv.io/x/gocv v0.35.0/go.mod h1:oc6FvfYqfBp99p+yOEzs9tbYF9gOrAQSeL/dyIPefJU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= -golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= -golang.org/x/image v0.0.0-20220617043117-41969df76e82/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 h1:GZokNIeuVkl3aZHJchRrr13WCsols02MLUcz1U9is6M= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200925191224-5d1fdd8fa346/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= -golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -178,15 +124,5 @@ periph.io/x/conn/v3 v3.7.0 h1:f1EXLn4pkf7AEWwkol2gilCNZ0ElY+bxS4WE2PQXfrA= periph.io/x/conn/v3 v3.7.0/go.mod h1:ypY7UVxgDbP9PJGwFSVelRRagxyXYfttVh7hJZUHEhg= periph.io/x/host/v3 v3.8.2 h1:ayKUDzgUCN0g8+/xM9GTkWaOBhSLVcVHGTfjAOi8OsQ= periph.io/x/host/v3 v3.8.2/go.mod h1:yFL76AesNHR68PboofSWYaQTKmvPXsQH2Apvp/ls/K4= -tinygo.org/x/bluetooth v0.7.0 h1:7lU0VrauwccbLvb6AKHf4ZedFlxZIFwwqHWQD2fLWvA= -tinygo.org/x/bluetooth v0.7.0/go.mod h1:2hZPpfPDMR7Vvi6yMvyi83o8gYXeMKKsLfUnvmtBcjM= -tinygo.org/x/drivers v0.14.0/go.mod h1:uT2svMq3EpBZpKkGO+NQHjxjGf1f42ra4OnMMwQL2aI= -tinygo.org/x/drivers v0.15.1/go.mod h1:uT2svMq3EpBZpKkGO+NQHjxjGf1f42ra4OnMMwQL2aI= -tinygo.org/x/drivers v0.16.0/go.mod h1:uT2svMq3EpBZpKkGO+NQHjxjGf1f42ra4OnMMwQL2aI= -tinygo.org/x/drivers v0.19.0/go.mod h1:uJD/l1qWzxzLx+vcxaW0eY464N5RAgFi1zTVzASFdqI= -tinygo.org/x/drivers v0.25.0/go.mod h1:v+mXaA4cgpz/YZJ3ZPm/86bYQJAXTaYtMkHlVwbodbw= -tinygo.org/x/tinyfont v0.2.1/go.mod h1:eLqnYSrFRjt5STxWaMeOWJTzrKhXqpWw7nU3bPfKOAM= -tinygo.org/x/tinyfont v0.3.0/go.mod h1:+TV5q0KpwSGRWnN+ITijsIhrWYJkoUCp9MYELjKpAXk= -tinygo.org/x/tinyfont v0.4.0/go.mod h1:7nVj3j3geqBoPDzpFukAhF1C8AP9YocMsZy0HSAcGCA= -tinygo.org/x/tinyfs v0.1.0/go.mod h1:ysc8Y92iHfhTXeyEM9+c7zviUQ4fN9UCFgSOFfMWv20= -tinygo.org/x/tinyterm v0.1.0/go.mod h1:/DDhNnGwNF2/tNgHywvyZuCGnbH3ov49Z/6e8LPLRR4= +tinygo.org/x/bluetooth v0.8.0 h1:WmuRebsODcUUIlGhesyuNRIAEIUCErhKlrZ9K9aimdI= +tinygo.org/x/bluetooth v0.8.0/go.mod h1:cfsVc0/nGo3nzi6+CeQaXb+anNlmEnSABkKsxer8OAE= diff --git a/gobottest/gobottest.go b/gobottest/gobottest.go deleted file mode 100644 index 68808dd26..000000000 --- a/gobottest/gobottest.go +++ /dev/null @@ -1,45 +0,0 @@ -package gobottest - -import ( - "fmt" - "os" - "os/exec" - "reflect" - "runtime" - "strings" - "testing" -) - -var errFunc = func(t *testing.T, message string) { - t.Errorf(message) -} - -func logFailure(t *testing.T, message string) { - _, file, line, _ := runtime.Caller(2) - s := strings.Split(file, "/") - errFunc(t, fmt.Sprintf("%v:%v: %v", s[len(s)-1], line, message)) -} - -// Assert checks if a and b are equal, emits a t.Errorf if they are not equal. -func Assert(t *testing.T, a interface{}, b interface{}) { - if !reflect.DeepEqual(a, b) { - logFailure(t, fmt.Sprintf("%v - \"%v\", should equal, %v - \"%v\"", - a, reflect.TypeOf(a), b, reflect.TypeOf(b))) - } -} - -// Refute checks if a and b are equal, emits a t.Errorf if they are equal. -func Refute(t *testing.T, a interface{}, b interface{}) { - if reflect.DeepEqual(a, b) { - logFailure(t, fmt.Sprintf("%v - \"%v\", should not equal, %v - \"%v\"", - a, reflect.TypeOf(a), b, reflect.TypeOf(b))) - } -} - -func ExecCommand(command string, args ...string) *exec.Cmd { - cs := []string{"-test.run=TestHelperProcess", "--", command} - cs = append(cs, args...) - cmd := exec.Command(os.Args[0], cs...) - cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"} - return cmd -} diff --git a/gobottest/gobottest_test.go b/gobottest/gobottest_test.go deleted file mode 100644 index 87b2c8a19..000000000 --- a/gobottest/gobottest_test.go +++ /dev/null @@ -1,42 +0,0 @@ -package gobottest - -import "testing" - -func TestAssert(t *testing.T) { - err := "" - errFunc = func(t *testing.T, message string) { - err = message - } - - Assert(t, 1, 1) - if err != "" { - t.Errorf("Assert failed: 1 should equal 1") - } - - Assert(t, 1, 2) - if err != `gobottest_test.go:16: 1 - "int", should equal, 2 - "int"` { - t.Errorf("Assert failed: 1 should not equal 2") - } -} - -func TestRefute(t *testing.T) { - err := "" - errFunc = func(t *testing.T, message string) { - err = message - } - - Refute(t, 1, 2) - if err != "" { - t.Errorf("Refute failed: 1 should not be 2") - } - - Refute(t, 1, 1) - if err != `gobottest_test.go:33: 1 - "int", should not equal, 1 - "int"` { - t.Errorf("Refute failed: 1 should not be 1") - } -} - -func TestExecCommand(t *testing.T) { - val := ExecCommand("echo", "hello") - Refute(t, val, nil) -} diff --git a/helpers_test.go b/helpers_test.go index b97cf7c03..dee5d39a1 100644 --- a/helpers_test.go +++ b/helpers_test.go @@ -23,8 +23,10 @@ type testDriver struct { Commander } -var testDriverStart = func() (err error) { return } -var testDriverHalt = func() (err error) { return } +var ( + testDriverStart = func() (err error) { return } + testDriverHalt = func() (err error) { return } +) func (t *testDriver) Start() (err error) { return testDriverStart() } func (t *testDriver) Halt() (err error) { return testDriverHalt() } @@ -51,8 +53,10 @@ type testAdaptor struct { port string } -var testAdaptorConnect = func() (err error) { return } -var testAdaptorFinalize = func() (err error) { return } +var ( + testAdaptorConnect = func() (err error) { return } + testAdaptorFinalize = func() (err error) { return } +) func (t *testAdaptor) Finalize() (err error) { return testAdaptorFinalize() } func (t *testAdaptor) Connect() (err error) { return testAdaptorConnect() } @@ -60,7 +64,7 @@ func (t *testAdaptor) Name() string { return t.name } func (t *testAdaptor) SetName(n string) { t.name = n } func (t *testAdaptor) Port() string { return t.port } -func newTestAdaptor(name string, port string) *testAdaptor { +func newTestAdaptor(name string, port string) *testAdaptor { //nolint:unparam // keep for tests return &testAdaptor{ name: name, port: port, diff --git a/master_test.go b/master_test.go index f6c9159de..e722a00e9 100644 --- a/master_test.go +++ b/master_test.go @@ -9,7 +9,7 @@ import ( "time" multierror "github.com/hashicorp/go-multierror" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) func initTestMaster() *Master { @@ -38,23 +38,23 @@ func initTestMaster1Robot() *Master { func TestNullReadWriteCloser(t *testing.T) { n := &NullReadWriteCloser{} i, _ := n.Write([]byte{1, 2, 3}) - gobottest.Assert(t, i, 3) + assert.Equal(t, 3, i) i, _ = n.Read(make([]byte, 10)) - gobottest.Assert(t, i, 10) - gobottest.Assert(t, n.Close(), nil) + assert.Equal(t, 10, i) + assert.NoError(t, n.Close()) } func TestMasterRobot(t *testing.T) { g := initTestMaster() - gobottest.Assert(t, g.Robot("Robot1").Name, "Robot1") - gobottest.Assert(t, g.Robot("Robot4"), (*Robot)(nil)) - gobottest.Assert(t, g.Robot("Robot4").Device("Device1"), (Device)(nil)) - gobottest.Assert(t, g.Robot("Robot4").Connection("Connection1"), (Connection)(nil)) - gobottest.Assert(t, g.Robot("Robot1").Device("Device4"), (Device)(nil)) - gobottest.Assert(t, g.Robot("Robot1").Device("Device1").Name(), "Device1") - gobottest.Assert(t, g.Robot("Robot1").Devices().Len(), 3) - gobottest.Assert(t, g.Robot("Robot1").Connection("Connection4"), (Connection)(nil)) - gobottest.Assert(t, g.Robot("Robot1").Connections().Len(), 3) + assert.Equal(t, "Robot1", g.Robot("Robot1").Name) + assert.Equal(t, (*Robot)(nil), g.Robot("Robot4")) + assert.Equal(t, (Device)(nil), g.Robot("Robot4").Device("Device1")) + assert.Equal(t, (Connection)(nil), g.Robot("Robot4").Connection("Connection1")) + assert.Equal(t, (Device)(nil), g.Robot("Robot1").Device("Device4")) + assert.Equal(t, "Device1", g.Robot("Robot1").Device("Device1").Name()) + assert.Equal(t, 3, g.Robot("Robot1").Devices().Len()) + assert.Equal(t, (Connection)(nil), g.Robot("Robot1").Connection("Connection4")) + assert.Equal(t, 3, g.Robot("Robot1").Connections().Len()) } func TestMasterToJSON(t *testing.T) { @@ -63,15 +63,15 @@ func TestMasterToJSON(t *testing.T) { return nil }) json := NewJSONMaster(g) - gobottest.Assert(t, len(json.Robots), g.Robots().Len()) - gobottest.Assert(t, len(json.Commands), len(g.Commands())) + assert.Equal(t, g.Robots().Len(), len(json.Robots)) + assert.Equal(t, len(g.Commands()), len(json.Commands)) } func TestMasterStart(t *testing.T) { g := initTestMaster() - gobottest.Assert(t, g.Start(), nil) - gobottest.Assert(t, g.Stop(), nil) - gobottest.Assert(t, g.Running(), false) + assert.NoError(t, g.Start()) + assert.NoError(t, g.Stop()) + assert.False(t, g.Running()) } func TestMasterStartAutoRun(t *testing.T) { @@ -79,11 +79,11 @@ func TestMasterStartAutoRun(t *testing.T) { g.AddRobot(newTestRobot("Robot99")) go func() { _ = g.Start() }() time.Sleep(10 * time.Millisecond) - gobottest.Assert(t, g.Running(), true) + assert.True(t, g.Running()) // stop it - gobottest.Assert(t, g.Stop(), nil) - gobottest.Assert(t, g.Running(), false) + assert.NoError(t, g.Stop()) + assert.False(t, g.Running()) } func TestMasterStartDriverErrors(t *testing.T) { @@ -98,8 +98,8 @@ func TestMasterStartDriverErrors(t *testing.T) { want = multierror.Append(want, e) want = multierror.Append(want, e) - gobottest.Assert(t, g.Start(), want) - gobottest.Assert(t, g.Stop(), nil) + assert.Equal(t, want, g.Start()) + assert.NoError(t, g.Stop()) testDriverStart = func() (err error) { return } } @@ -119,7 +119,7 @@ func TestMasterHaltFromRobotDriverErrors(t *testing.T) { want = multierror.Append(want, e) } - gobottest.Assert(t, g.Start(), want) + assert.Equal(t, want, g.Start()) } func TestMasterStartRobotAdaptorErrors(t *testing.T) { @@ -137,8 +137,8 @@ func TestMasterStartRobotAdaptorErrors(t *testing.T) { want = multierror.Append(want, e) } - gobottest.Assert(t, g.Start(), want) - gobottest.Assert(t, g.Stop(), nil) + assert.Equal(t, want, g.Start()) + assert.NoError(t, g.Stop()) testAdaptorConnect = func() (err error) { return } } @@ -158,5 +158,5 @@ func TestMasterFinalizeErrors(t *testing.T) { want = multierror.Append(want, e) } - gobottest.Assert(t, g.Start(), want) + assert.Equal(t, want, g.Start()) } diff --git a/platforms/adaptors/digitalpinsadaptor.go b/platforms/adaptors/digitalpinsadaptor.go index a171134e4..7ffc9de10 100644 --- a/platforms/adaptors/digitalpinsadaptor.go +++ b/platforms/adaptors/digitalpinsadaptor.go @@ -6,12 +6,15 @@ import ( "time" "github.com/hashicorp/go-multierror" + "gobot.io/x/gobot/v2" "gobot.io/x/gobot/v2/system" ) -type digitalPinTranslator func(pin string) (chip string, line int, err error) -type digitalPinInitializer func(gobot.DigitalPinner) error +type ( + digitalPinTranslator func(pin string) (chip string, line int, err error) + digitalPinInitializer func(gobot.DigitalPinner) error +) type digitalPinsOptioner interface { setDigitalPinInitializer(digitalPinInitializer) @@ -29,6 +32,7 @@ type digitalPinsOptioner interface { detectedEdge string, seqno uint32, lseqno uint32)) prepareDigitalPinEventOnBothEdges(pin string, handler func(lineOffset int, timestamp time.Duration, detectedEdge string, seqno uint32, lseqno uint32)) + prepareDigitalPinPollForEdgeDetection(pin string, pollInterval time.Duration, pollQuitChan chan struct{}) } // DigitalPinsAdaptor is a adaptor for digital pins, normally used for composition in platforms. @@ -158,7 +162,8 @@ func WithGpioDebounce(pin string, period time.Duration) func(Optioner) { // WithGpioEventOnFallingEdge prepares the given input pin to be generate an event on falling edge. // This is working for inputs since Kernel 5.10, but will be ignored for outputs or with sysfs ABI. func WithGpioEventOnFallingEdge(pin string, handler func(lineOffset int, timestamp time.Duration, detectedEdge string, - seqno uint32, lseqno uint32)) func(Optioner) { + seqno uint32, lseqno uint32), +) func(Optioner) { return func(o Optioner) { a, ok := o.(digitalPinsOptioner) if ok { @@ -170,7 +175,8 @@ func WithGpioEventOnFallingEdge(pin string, handler func(lineOffset int, timesta // WithGpioEventOnRisingEdge prepares the given input pin to be generate an event on rising edge. // This is working for inputs since Kernel 5.10, but will be ignored for outputs or with sysfs ABI. func WithGpioEventOnRisingEdge(pin string, handler func(lineOffset int, timestamp time.Duration, detectedEdge string, - seqno uint32, lseqno uint32)) func(Optioner) { + seqno uint32, lseqno uint32), +) func(Optioner) { return func(o Optioner) { a, ok := o.(digitalPinsOptioner) if ok { @@ -182,7 +188,8 @@ func WithGpioEventOnRisingEdge(pin string, handler func(lineOffset int, timestam // WithGpioEventOnBothEdges prepares the given input pin to be generate an event on rising and falling edges. // This is working for inputs since Kernel 5.10, but will be ignored for outputs or with sysfs ABI. func WithGpioEventOnBothEdges(pin string, handler func(lineOffset int, timestamp time.Duration, detectedEdge string, - seqno uint32, lseqno uint32)) func(Optioner) { + seqno uint32, lseqno uint32), +) func(Optioner) { return func(o Optioner) { a, ok := o.(digitalPinsOptioner) if ok { @@ -191,6 +198,17 @@ func WithGpioEventOnBothEdges(pin string, handler func(lineOffset int, timestamp } } +// WithGpioPollForEdgeDetection prepares the given input pin to use a discrete input pin polling function together with +// edge detection. +func WithGpioPollForEdgeDetection(pin string, pollInterval time.Duration, pollQuitChan chan struct{}) func(Optioner) { + return func(o Optioner) { + a, ok := o.(digitalPinsOptioner) + if ok { + a.prepareDigitalPinPollForEdgeDetection(pin, pollInterval, pollQuitChan) + } + } +} + // Connect prepare new connection to digital pins. func (a *DigitalPinsAdaptor) Connect() error { a.mutex.Lock() @@ -336,7 +354,8 @@ func (a *DigitalPinsAdaptor) prepareDigitalPinDebounce(id string, period time.Du } func (a *DigitalPinsAdaptor) prepareDigitalPinEventOnFallingEdge(id string, handler func(int, time.Duration, string, - uint32, uint32)) { + uint32, uint32), +) { if a.pinOptions == nil { a.pinOptions = make(map[string][]func(gobot.DigitalPinOptioner) bool) } @@ -345,7 +364,8 @@ func (a *DigitalPinsAdaptor) prepareDigitalPinEventOnFallingEdge(id string, hand } func (a *DigitalPinsAdaptor) prepareDigitalPinEventOnRisingEdge(id string, handler func(int, time.Duration, string, - uint32, uint32)) { + uint32, uint32), +) { if a.pinOptions == nil { a.pinOptions = make(map[string][]func(gobot.DigitalPinOptioner) bool) } @@ -354,7 +374,8 @@ func (a *DigitalPinsAdaptor) prepareDigitalPinEventOnRisingEdge(id string, handl } func (a *DigitalPinsAdaptor) prepareDigitalPinEventOnBothEdges(id string, handler func(int, time.Duration, string, - uint32, uint32)) { + uint32, uint32), +) { if a.pinOptions == nil { a.pinOptions = make(map[string][]func(gobot.DigitalPinOptioner) bool) } @@ -362,6 +383,18 @@ func (a *DigitalPinsAdaptor) prepareDigitalPinEventOnBothEdges(id string, handle a.pinOptions[id] = append(a.pinOptions[id], system.WithPinEventOnBothEdges(handler)) } +func (a *DigitalPinsAdaptor) prepareDigitalPinPollForEdgeDetection( + id string, + pollInterval time.Duration, + pollQuitChan chan struct{}, +) { + if a.pinOptions == nil { + a.pinOptions = make(map[string][]func(gobot.DigitalPinOptioner) bool) + } + + a.pinOptions[id] = append(a.pinOptions[id], system.WithPinPollForEdgeDetection(pollInterval, pollQuitChan)) +} + func (a *DigitalPinsAdaptor) digitalPin(id string, opts ...func(gobot.DigitalPinOptioner) bool) (gobot.DigitalPinner, error) { if a.pins == nil { return nil, fmt.Errorf("not connected for pin %s", id) diff --git a/platforms/adaptors/digitalpinsadaptor_test.go b/platforms/adaptors/digitalpinsadaptor_test.go index 954898ecf..f25feda58 100644 --- a/platforms/adaptors/digitalpinsadaptor_test.go +++ b/platforms/adaptors/digitalpinsadaptor_test.go @@ -1,26 +1,25 @@ package adaptors import ( - "errors" "fmt" - "strings" - "testing" - "time" - "runtime" "strconv" "sync" + "testing" + "time" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" "gobot.io/x/gobot/v2/drivers/gpio" - "gobot.io/x/gobot/v2/gobottest" "gobot.io/x/gobot/v2/system" ) // make sure that this adaptor fulfills all the required interfaces -var _ gobot.DigitalPinnerProvider = (*DigitalPinsAdaptor)(nil) -var _ gpio.DigitalReader = (*DigitalPinsAdaptor)(nil) -var _ gpio.DigitalWriter = (*DigitalPinsAdaptor)(nil) +var ( + _ gobot.DigitalPinnerProvider = (*DigitalPinsAdaptor)(nil) + _ gpio.DigitalReader = (*DigitalPinsAdaptor)(nil) + _ gpio.DigitalWriter = (*DigitalPinsAdaptor)(nil) +) func initTestDigitalPinsAdaptorWithMockedFilesystem(mockPaths []string) (*DigitalPinsAdaptor, *system.MockFilesystem) { sys := system.NewAccesser() @@ -50,7 +49,7 @@ func TestDigitalPinsWithGpiosActiveLow(t *testing.T) { // act a := NewDigitalPinsAdaptor(sys, translate, WithGpiosActiveLow("1", "12", "33")) // assert - gobottest.Assert(t, len(a.pinOptions), 3) + assert.Equal(t, 3, len(a.pinOptions)) } func TestDigitalPinsConnect(t *testing.T) { @@ -58,18 +57,18 @@ func TestDigitalPinsConnect(t *testing.T) { sys := system.NewAccesser() a := NewDigitalPinsAdaptor(sys, translate) - gobottest.Assert(t, a.pins, (map[string]gobot.DigitalPinner)(nil)) + assert.Equal(t, (map[string]gobot.DigitalPinner)(nil), a.pins) _, err := a.DigitalRead("13") - gobottest.Assert(t, err.Error(), "not connected for pin 13") + assert.ErrorContains(t, err, "not connected for pin 13") err = a.DigitalWrite("7", 1) - gobottest.Assert(t, err.Error(), "not connected for pin 7") + assert.ErrorContains(t, err, "not connected for pin 7") err = a.Connect() - gobottest.Assert(t, err, nil) - gobottest.Refute(t, a.pins, (map[string]gobot.DigitalPinner)(nil)) - gobottest.Assert(t, len(a.pins), 0) + assert.NoError(t, err) + assert.NotEqual(t, (map[string]gobot.DigitalPinner)(nil), a.pins) + assert.Equal(t, 0, len(a.pins)) } func TestDigitalPinsFinalize(t *testing.T) { @@ -84,24 +83,24 @@ func TestDigitalPinsFinalize(t *testing.T) { fs := sys.UseMockFilesystem(mockedPaths) a := NewDigitalPinsAdaptor(sys, testDigitalPinTranslator) // assert that finalize before connect is working - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) // arrange - gobottest.Assert(t, a.Connect(), nil) - gobottest.Assert(t, a.DigitalWrite("3", 1), nil) - gobottest.Assert(t, len(a.pins), 1) + assert.NoError(t, a.Connect()) + assert.NoError(t, a.DigitalWrite("3", 1)) + assert.Equal(t, 1, len(a.pins)) // act err := a.Finalize() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.pins), 0) + assert.NoError(t, err) + assert.Equal(t, 0, len(a.pins)) // assert that finalize after finalize is working - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) // arrange missing sysfs file - gobottest.Assert(t, a.Connect(), nil) - gobottest.Assert(t, a.DigitalWrite("3", 2), nil) + assert.NoError(t, a.Connect()) + assert.NoError(t, a.DigitalWrite("3", 2)) delete(fs.Files, "/sys/class/gpio/unexport") err = a.Finalize() - gobottest.Assert(t, strings.Contains(err.Error(), "/sys/class/gpio/unexport: no such file"), true) + assert.Contains(t, err.Error(), "/sys/class/gpio/unexport: no such file") } func TestDigitalPinsReConnect(t *testing.T) { @@ -113,15 +112,15 @@ func TestDigitalPinsReConnect(t *testing.T) { "/sys/class/gpio/gpio15/value", } a, _ := initTestDigitalPinsAdaptorWithMockedFilesystem(mockedPaths) - gobottest.Assert(t, a.DigitalWrite("4", 1), nil) - gobottest.Assert(t, len(a.pins), 1) - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.DigitalWrite("4", 1)) + assert.Equal(t, 1, len(a.pins)) + assert.NoError(t, a.Finalize()) // act err := a.Connect() // assert - gobottest.Assert(t, err, nil) - gobottest.Refute(t, a.pins, nil) - gobottest.Assert(t, len(a.pins), 0) + assert.NoError(t, err) + assert.NotNil(t, a.pins) + assert.Equal(t, 0, len(a.pins)) } func TestDigitalIO(t *testing.T) { @@ -134,11 +133,11 @@ func TestDigitalIO(t *testing.T) { a, _ := initTestDigitalPinsAdaptorWithMockedFilesystem(mockedPaths) err := a.DigitalWrite("14", 1) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) i, err := a.DigitalRead("14") - gobottest.Assert(t, err, nil) - gobottest.Assert(t, i, 1) + assert.NoError(t, err) + assert.Equal(t, 1, i) } func TestDigitalRead(t *testing.T) { @@ -154,18 +153,18 @@ func TestDigitalRead(t *testing.T) { // assert read correct value without error i, err := a.DigitalRead("13") - gobottest.Assert(t, err, nil) - gobottest.Assert(t, i, 1) + assert.NoError(t, err) + assert.Equal(t, 1, i) // assert error bubbling for read errors fs.WithReadError = true _, err = a.DigitalRead("13") - gobottest.Assert(t, err, errors.New("read error")) + assert.ErrorContains(t, err, "read error") // assert error bubbling for write errors fs.WithWriteError = true _, err = a.DigitalRead("7") - gobottest.Assert(t, err, errors.New("write error")) + assert.ErrorContains(t, err, "write error") } func TestDigitalReadWithGpiosActiveLow(t *testing.T) { @@ -194,12 +193,12 @@ func TestDigitalReadWithGpiosActiveLow(t *testing.T) { got1, err1 := a.DigitalRead("14") // for a new pin got2, err2 := a.DigitalRead("15") // for an existing pin (calls ApplyOptions()) // assert - gobottest.Assert(t, err1, nil) - gobottest.Assert(t, err2, nil) - gobottest.Assert(t, got1, 1) // there is no mechanism to negate mocked values - gobottest.Assert(t, got2, 0) - gobottest.Assert(t, fs.Files["/sys/class/gpio/gpio25/active_low"].Contents, "1") - gobottest.Assert(t, fs.Files["/sys/class/gpio/gpio26/active_low"].Contents, "1") + assert.NoError(t, err1) + assert.NoError(t, err2) + assert.Equal(t, 1, got1) // there is no mechanism to negate mocked values + assert.Equal(t, 0, got2) + assert.Equal(t, "1", fs.Files["/sys/class/gpio/gpio25/active_low"].Contents) + assert.Equal(t, "1", fs.Files["/sys/class/gpio/gpio26/active_low"].Contents) } func TestDigitalWrite(t *testing.T) { @@ -216,9 +215,10 @@ func TestDigitalWrite(t *testing.T) { WithGpiosPullUp("7")(a) WithGpiosOpenDrain("7")(a) WithGpioEventOnFallingEdge("7", gpioEventHandler)(a) + WithGpioPollForEdgeDetection("7", 0, nil)(a) err := a.DigitalWrite("7", 1) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files["/sys/class/gpio/gpio18/value"].Contents, "1") + assert.NoError(t, err) + assert.Equal(t, "1", fs.Files["/sys/class/gpio/gpio18/value"].Contents) // assert second write to same pin without error and just ignore unsupported options WithGpiosPullDown("7")(a) @@ -226,15 +226,15 @@ func TestDigitalWrite(t *testing.T) { WithGpioDebounce("7", 2*time.Second)(a) WithGpioEventOnRisingEdge("7", gpioEventHandler)(a) err = a.DigitalWrite("7", 1) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) // assert error on bad id - gobottest.Assert(t, a.DigitalWrite("notexist", 1), errors.New("not a valid pin")) + assert.ErrorContains(t, a.DigitalWrite("notexist", 1), "not a valid pin") // assert error bubbling fs.WithWriteError = true err = a.DigitalWrite("7", 0) - gobottest.Assert(t, err, errors.New("write error")) + assert.ErrorContains(t, err, "write error") } func TestDigitalWriteWithGpiosActiveLow(t *testing.T) { @@ -252,9 +252,9 @@ func TestDigitalWriteWithGpiosActiveLow(t *testing.T) { // act err := a.DigitalWrite("8", 2) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files["/sys/class/gpio/gpio19/value"].Contents, "2") - gobottest.Assert(t, fs.Files["/sys/class/gpio/gpio19/active_low"].Contents, "1") + assert.NoError(t, err) + assert.Equal(t, "2", fs.Files["/sys/class/gpio/gpio19/value"].Contents) + assert.Equal(t, "1", fs.Files["/sys/class/gpio/gpio19/active_low"].Contents) } func TestDigitalPinConcurrency(t *testing.T) { diff --git a/platforms/adaptors/i2cbusadaptor_test.go b/platforms/adaptors/i2cbusadaptor_test.go index b76ee0fd5..f514bdccb 100644 --- a/platforms/adaptors/i2cbusadaptor_test.go +++ b/platforms/adaptors/i2cbusadaptor_test.go @@ -2,11 +2,10 @@ package adaptors import ( "fmt" - "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2/drivers/i2c" - "gobot.io/x/gobot/v2/gobottest" "gobot.io/x/gobot/v2/system" ) @@ -34,22 +33,22 @@ func initTestI2cAdaptorWithMockedFilesystem(mockPaths []string) (*I2cBusAdaptor, func TestI2cWorkflow(t *testing.T) { a, _ := initTestI2cAdaptorWithMockedFilesystem([]string{i2cBus1}) - gobottest.Assert(t, len(a.buses), 0) + assert.Equal(t, 0, len(a.buses)) con, err := a.GetI2cConnection(0xff, 1) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.buses), 1) + assert.NoError(t, err) + assert.Equal(t, 1, len(a.buses)) _, err = con.Write([]byte{0x00, 0x01}) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) data := []byte{42, 42} _, err = con.Read(data) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, data, []byte{0x00, 0x01}) + assert.NoError(t, err) + assert.Equal(t, []byte{0x00, 0x01}, data) - gobottest.Assert(t, a.Finalize(), nil) - gobottest.Assert(t, len(a.buses), 0) + assert.NoError(t, a.Finalize()) + assert.Equal(t, 0, len(a.buses)) } func TestI2cGetI2cConnection(t *testing.T) { @@ -57,58 +56,58 @@ func TestI2cGetI2cConnection(t *testing.T) { a, _ := initTestI2cAdaptorWithMockedFilesystem([]string{i2cBus1}) // assert working connection c1, e1 := a.GetI2cConnection(0xff, 1) - gobottest.Assert(t, e1, nil) - gobottest.Refute(t, c1, nil) - gobottest.Assert(t, len(a.buses), 1) + assert.NoError(t, e1) + assert.NotNil(t, c1) + assert.Equal(t, 1, len(a.buses)) // assert invalid bus gets error c2, e2 := a.GetI2cConnection(0x01, 99) - gobottest.Assert(t, e2, fmt.Errorf("99 not valid")) - gobottest.Assert(t, c2, nil) - gobottest.Assert(t, len(a.buses), 1) + assert.ErrorContains(t, e2, "99 not valid") + assert.Nil(t, c2) + assert.Equal(t, 1, len(a.buses)) // assert unconnected gets error - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) c3, e3 := a.GetI2cConnection(0x01, 99) - gobottest.Assert(t, e3, fmt.Errorf("not connected")) - gobottest.Assert(t, c3, nil) - gobottest.Assert(t, len(a.buses), 0) + assert.ErrorContains(t, e3, "not connected") + assert.Nil(t, c3) + assert.Equal(t, 0, len(a.buses)) } func TestI2cFinalize(t *testing.T) { // arrange a, fs := initTestI2cAdaptorWithMockedFilesystem([]string{i2cBus1}) // assert that finalize before connect is working - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) // arrange - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) _, _ = a.GetI2cConnection(0xaf, 1) - gobottest.Assert(t, len(a.buses), 1) + assert.Equal(t, 1, len(a.buses)) // assert that Finalize after GetI2cConnection is working and clean up - gobottest.Assert(t, a.Finalize(), nil) - gobottest.Assert(t, len(a.buses), 0) + assert.NoError(t, a.Finalize()) + assert.Equal(t, 0, len(a.buses)) // assert that finalize after finalize is working - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) // assert that close error is recognized - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) con, _ := a.GetI2cConnection(0xbf, 1) - gobottest.Assert(t, len(a.buses), 1) + assert.Equal(t, 1, len(a.buses)) _, _ = con.Write([]byte{0xbf}) fs.WithCloseError = true err := a.Finalize() - gobottest.Assert(t, strings.Contains(err.Error(), "close error"), true) + assert.Contains(t, err.Error(), "close error") } func TestI2cReConnect(t *testing.T) { // arrange a, _ := initTestI2cAdaptorWithMockedFilesystem([]string{i2cBus1}) - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) // act - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) // assert - gobottest.Refute(t, a.buses, nil) - gobottest.Assert(t, len(a.buses), 0) + assert.NotNil(t, a.buses) + assert.Equal(t, 0, len(a.buses)) } func TestI2cGetDefaultBus(t *testing.T) { a := NewI2cBusAdaptor(nil, nil, 2) - gobottest.Assert(t, a.DefaultI2cBus(), 2) + assert.Equal(t, 2, a.DefaultI2cBus()) } diff --git a/platforms/adaptors/pwmpinsadaptor.go b/platforms/adaptors/pwmpinsadaptor.go index 11c2969bf..f1b88de91 100644 --- a/platforms/adaptors/pwmpinsadaptor.go +++ b/platforms/adaptors/pwmpinsadaptor.go @@ -15,8 +15,10 @@ import ( // 100ns = 10MHz, 10ns = 100MHz, 1ns = 1GHz const pwmPeriodDefault = 10000000 // 10 ms = 100 Hz -type pwmPinTranslator func(pin string) (path string, channel int, err error) -type pwmPinInitializer func(gobot.PWMPinner) error +type ( + pwmPinTranslator func(pin string) (path string, channel int, err error) + pwmPinInitializer func(gobot.PWMPinner) error +) type pwmPinsOption interface { setInitializer(pwmPinInitializer) @@ -191,7 +193,7 @@ func (a *PWMPinsAdaptor) getDefaultInitializer() func(gobot.PWMPinner) error { return err } } - if err := setPeriod(pin, a.periodDefault, false); err != nil { + if err := setPeriod(pin, a.periodDefault, a.adjustDutyOnSetPeriod); err != nil { return err } // period needs to be set >1 before all next statements @@ -228,7 +230,7 @@ func (a *PWMPinsAdaptor) pwmPin(id string) (gobot.PWMPinner, error) { // also this value will be adjusted in the same ratio. The order of writing the values must be observed, otherwise an // error occur "write error: Invalid argument". func setPeriod(pin gobot.PWMPinner, period uint32, adjustDuty bool) error { - var errorBase = fmt.Sprintf("setPeriod(%v, %d) failed", pin, period) + errorBase := fmt.Sprintf("setPeriod(%v, %d) failed", pin, period) var oldDuty uint32 var err error @@ -255,11 +257,11 @@ func setPeriod(pin gobot.PWMPinner, period uint32, adjustDuty bool) error { if err := pin.SetPeriod(period); err != nil { return fmt.Errorf("%s with '%v'", errorBase, err) } - if err := pin.SetDutyCycle(uint32(duty)); err != nil { + if err := pin.SetDutyCycle(duty); err != nil { return fmt.Errorf("%s with '%v'", errorBase, err) } } else { - if err := pin.SetDutyCycle(uint32(duty)); err != nil { + if err := pin.SetDutyCycle(duty); err != nil { return fmt.Errorf("%s with '%v'", errorBase, err) } if err := pin.SetPeriod(period); err != nil { diff --git a/platforms/adaptors/pwmpinsadaptor_test.go b/platforms/adaptors/pwmpinsadaptor_test.go index 87f8f2f58..15ff4bc23 100644 --- a/platforms/adaptors/pwmpinsadaptor_test.go +++ b/platforms/adaptors/pwmpinsadaptor_test.go @@ -2,20 +2,21 @@ package adaptors import ( "fmt" + "log" "runtime" "strconv" "strings" "sync" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" "gobot.io/x/gobot/v2/drivers/gpio" - "gobot.io/x/gobot/v2/gobottest" "gobot.io/x/gobot/v2/system" ) const ( - pwmDir = "/sys/devices/platform/ff680020.pwm/pwm/pwmchip3/" + pwmDir = "/sys/devices/platform/ff680020.pwm/pwm/pwmchip3/" //nolint:gosec // false positive pwmPwm0Dir = pwmDir + "pwm44/" pwmExportPath = pwmDir + "export" pwmUnexportPath = pwmDir + "unexport" @@ -35,9 +36,11 @@ var pwmMockPaths = []string{ } // make sure that this PWMPinsAdaptor fulfills all the required interfaces -var _ gobot.PWMPinnerProvider = (*PWMPinsAdaptor)(nil) -var _ gpio.PwmWriter = (*PWMPinsAdaptor)(nil) -var _ gpio.ServoWriter = (*PWMPinsAdaptor)(nil) +var ( + _ gobot.PWMPinnerProvider = (*PWMPinsAdaptor)(nil) + _ gpio.PwmWriter = (*PWMPinsAdaptor)(nil) + _ gpio.ServoWriter = (*PWMPinsAdaptor)(nil) +) func initTestPWMPinsAdaptorWithMockedFilesystem(mockPaths []string) (*PWMPinsAdaptor, *system.MockFilesystem) { sys := system.NewAccesser() @@ -68,10 +71,10 @@ func TestNewPWMPinsAdaptor(t *testing.T) { // act a := NewPWMPinsAdaptor(system.NewAccesser(), translate) // assert - gobottest.Assert(t, a.periodDefault, uint32(pwmPeriodDefault)) - gobottest.Assert(t, a.polarityNormalIdentifier, "normal") - gobottest.Assert(t, a.polarityInvertedIdentifier, "inverted") - gobottest.Assert(t, a.adjustDutyOnSetPeriod, true) + assert.Equal(t, uint32(pwmPeriodDefault), a.periodDefault) + assert.Equal(t, "normal", a.polarityNormalIdentifier) + assert.Equal(t, "inverted", a.polarityInvertedIdentifier) + assert.True(t, a.adjustDutyOnSetPeriod) } func TestWithPWMPinInitializer(t *testing.T) { @@ -85,7 +88,7 @@ func TestWithPWMPinInitializer(t *testing.T) { WithPWMPinInitializer(newInitializer)) // assert err := a.initialize(nil) - gobottest.Assert(t, err, wantErr) + assert.Equal(t, wantErr, err) } func TestWithPWMPinDefaultPeriod(t *testing.T) { @@ -95,7 +98,7 @@ func TestWithPWMPinDefaultPeriod(t *testing.T) { // act WithPWMPinDefaultPeriod(newPeriod)(a) // assert - gobottest.Assert(t, a.periodDefault, newPeriod) + assert.Equal(t, newPeriod, a.periodDefault) } func TestWithPolarityInvertedIdentifier(t *testing.T) { @@ -105,21 +108,21 @@ func TestWithPolarityInvertedIdentifier(t *testing.T) { // act WithPolarityInvertedIdentifier(newPolarityIdent)(a) // assert - gobottest.Assert(t, a.polarityInvertedIdentifier, newPolarityIdent) + assert.Equal(t, newPolarityIdent, a.polarityInvertedIdentifier) } func TestPWMPinsConnect(t *testing.T) { translate := func(pin string) (chip string, line int, err error) { return } a := NewPWMPinsAdaptor(system.NewAccesser(), translate) - gobottest.Assert(t, a.pins, (map[string]gobot.PWMPinner)(nil)) + assert.Equal(t, (map[string]gobot.PWMPinner)(nil), a.pins) err := a.PwmWrite("33", 1) - gobottest.Assert(t, err.Error(), "not connected") + assert.ErrorContains(t, err, "not connected") err = a.Connect() - gobottest.Assert(t, err, nil) - gobottest.Refute(t, a.pins, (map[string]gobot.PWMPinner)(nil)) - gobottest.Assert(t, len(a.pins), 0) + assert.NoError(t, err) + assert.NotEqual(t, (map[string]gobot.PWMPinner)(nil), a.pins) + assert.Equal(t, 0, len(a.pins)) } func TestPWMPinsFinalize(t *testing.T) { @@ -127,98 +130,100 @@ func TestPWMPinsFinalize(t *testing.T) { sys := system.NewAccesser() fs := sys.UseMockFilesystem(pwmMockPaths) a := NewPWMPinsAdaptor(sys, testPWMPinTranslator) + fs.Files[pwmPeriodPath].Contents = "0" + fs.Files[pwmDutyCyclePath].Contents = "0" // assert that finalize before connect is working - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) // arrange - gobottest.Assert(t, a.Connect(), nil) - gobottest.Assert(t, a.PwmWrite("33", 1), nil) - gobottest.Assert(t, len(a.pins), 1) + assert.NoError(t, a.Connect()) + assert.NoError(t, a.PwmWrite("33", 1)) + assert.Equal(t, 1, len(a.pins)) // act err := a.Finalize() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.pins), 0) + assert.NoError(t, err) + assert.Equal(t, 0, len(a.pins)) // assert that finalize after finalize is working - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) // arrange missing sysfs file - gobottest.Assert(t, a.Connect(), nil) - gobottest.Assert(t, a.PwmWrite("33", 2), nil) + assert.NoError(t, a.Connect()) + assert.NoError(t, a.PwmWrite("33", 2)) delete(fs.Files, pwmUnexportPath) err = a.Finalize() - gobottest.Assert(t, strings.Contains(err.Error(), pwmUnexportPath+": no such file"), true) + assert.Contains(t, err.Error(), pwmUnexportPath+": no such file") // arrange write error - gobottest.Assert(t, a.Connect(), nil) - gobottest.Assert(t, a.PwmWrite("33", 2), nil) + assert.NoError(t, a.Connect()) + assert.NoError(t, a.PwmWrite("33", 2)) fs.WithWriteError = true err = a.Finalize() - gobottest.Assert(t, strings.Contains(err.Error(), "write error"), true) + assert.Contains(t, err.Error(), "write error") } func TestPWMPinsReConnect(t *testing.T) { // arrange a, _ := initTestPWMPinsAdaptorWithMockedFilesystem(pwmMockPaths) - gobottest.Assert(t, a.PwmWrite("33", 1), nil) - gobottest.Assert(t, len(a.pins), 1) - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.PwmWrite("33", 1)) + assert.Equal(t, 1, len(a.pins)) + assert.NoError(t, a.Finalize()) // act err := a.Connect() // assert - gobottest.Assert(t, err, nil) - gobottest.Refute(t, a.pins, nil) - gobottest.Assert(t, len(a.pins), 0) + assert.NoError(t, err) + assert.NotNil(t, a.pins) + assert.Equal(t, 0, len(a.pins)) } func TestPwmWrite(t *testing.T) { a, fs := initTestPWMPinsAdaptorWithMockedFilesystem(pwmMockPaths) err := a.PwmWrite("33", 100) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) - gobottest.Assert(t, fs.Files[pwmExportPath].Contents, "44") - gobottest.Assert(t, fs.Files[pwmEnablePath].Contents, "1") - gobottest.Assert(t, fs.Files[pwmPeriodPath].Contents, fmt.Sprintf("%d", a.periodDefault)) - gobottest.Assert(t, fs.Files[pwmDutyCyclePath].Contents, "3921568") - gobottest.Assert(t, fs.Files[pwmPolarityPath].Contents, "normal") + assert.Equal(t, "44", fs.Files[pwmExportPath].Contents) + assert.Equal(t, "1", fs.Files[pwmEnablePath].Contents) + assert.Equal(t, fmt.Sprintf("%d", a.periodDefault), fs.Files[pwmPeriodPath].Contents) + assert.Equal(t, "3921568", fs.Files[pwmDutyCyclePath].Contents) + assert.Equal(t, "normal", fs.Files[pwmPolarityPath].Contents) err = a.PwmWrite("notexist", 42) - gobottest.Assert(t, err.Error(), "'notexist' is not a valid id of a PWM pin") + assert.ErrorContains(t, err, "'notexist' is not a valid id of a PWM pin") fs.WithWriteError = true err = a.PwmWrite("33", 100) - gobottest.Assert(t, strings.Contains(err.Error(), "write error"), true) + assert.Contains(t, err.Error(), "write error") fs.WithWriteError = false fs.WithReadError = true err = a.PwmWrite("33", 100) - gobottest.Assert(t, strings.Contains(err.Error(), "read error"), true) + assert.Contains(t, err.Error(), "read error") } func TestServoWrite(t *testing.T) { a, fs := initTestPWMPinsAdaptorWithMockedFilesystem(pwmMockPaths) err := a.ServoWrite("33", 0) - gobottest.Assert(t, fs.Files[pwmExportPath].Contents, "44") - gobottest.Assert(t, fs.Files[pwmEnablePath].Contents, "1") - gobottest.Assert(t, fs.Files[pwmPeriodPath].Contents, fmt.Sprintf("%d", a.periodDefault)) - gobottest.Assert(t, fs.Files[pwmDutyCyclePath].Contents, "500000") - gobottest.Assert(t, fs.Files[pwmPolarityPath].Contents, "normal") - gobottest.Assert(t, err, nil) + assert.Equal(t, "44", fs.Files[pwmExportPath].Contents) + assert.Equal(t, "1", fs.Files[pwmEnablePath].Contents) + assert.Equal(t, fmt.Sprintf("%d", a.periodDefault), fs.Files[pwmPeriodPath].Contents) + assert.Equal(t, "500000", fs.Files[pwmDutyCyclePath].Contents) + assert.Equal(t, "normal", fs.Files[pwmPolarityPath].Contents) + assert.NoError(t, err) err = a.ServoWrite("33", 180) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files[pwmDutyCyclePath].Contents, "2000000") + assert.NoError(t, err) + assert.Equal(t, "2000000", fs.Files[pwmDutyCyclePath].Contents) err = a.ServoWrite("notexist", 42) - gobottest.Assert(t, err.Error(), "'notexist' is not a valid id of a PWM pin") + assert.ErrorContains(t, err, "'notexist' is not a valid id of a PWM pin") fs.WithWriteError = true err = a.ServoWrite("33", 100) - gobottest.Assert(t, strings.Contains(err.Error(), "write error"), true) + assert.Contains(t, err.Error(), "write error") fs.WithWriteError = false fs.WithReadError = true err = a.ServoWrite("33", 100) - gobottest.Assert(t, strings.Contains(err.Error(), "read error"), true) + assert.Contains(t, err.Error(), "read error") } func TestSetPeriod(t *testing.T) { @@ -228,25 +233,25 @@ func TestSetPeriod(t *testing.T) { // act err := a.SetPeriod("33", newPeriod) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files[pwmExportPath].Contents, "44") - gobottest.Assert(t, fs.Files[pwmEnablePath].Contents, "1") - gobottest.Assert(t, fs.Files[pwmPeriodPath].Contents, fmt.Sprintf("%d", newPeriod)) - gobottest.Assert(t, fs.Files[pwmDutyCyclePath].Contents, "0") - gobottest.Assert(t, fs.Files[pwmPolarityPath].Contents, "normal") + assert.NoError(t, err) + assert.Equal(t, "44", fs.Files[pwmExportPath].Contents) + assert.Equal(t, "1", fs.Files[pwmEnablePath].Contents) + assert.Equal(t, fmt.Sprintf("%d", newPeriod), fs.Files[pwmPeriodPath].Contents) + assert.Equal(t, "0", fs.Files[pwmDutyCyclePath].Contents) + assert.Equal(t, "normal", fs.Files[pwmPolarityPath].Contents) // arrange test for automatic adjustment of duty cycle to lower value err = a.PwmWrite("33", 127) // 127 is a little bit smaller than 50% of period - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files[pwmDutyCyclePath].Contents, fmt.Sprintf("%d", 1270000)) + assert.NoError(t, err) + assert.Equal(t, fmt.Sprintf("%d", 1270000), fs.Files[pwmDutyCyclePath].Contents) newPeriod = newPeriod / 10 // act err = a.SetPeriod("33", newPeriod) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files[pwmDutyCyclePath].Contents, fmt.Sprintf("%d", 127000)) + assert.NoError(t, err) + assert.Equal(t, fmt.Sprintf("%d", 127000), fs.Files[pwmDutyCyclePath].Contents) // arrange test for automatic adjustment of duty cycle to higher value newPeriod = newPeriod * 20 @@ -255,27 +260,30 @@ func TestSetPeriod(t *testing.T) { err = a.SetPeriod("33", newPeriod) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files[pwmDutyCyclePath].Contents, fmt.Sprintf("%d", 2540000)) + assert.NoError(t, err) + assert.Equal(t, fmt.Sprintf("%d", 2540000), fs.Files[pwmDutyCyclePath].Contents) // act err = a.SetPeriod("not_exist", newPeriod) // assert - gobottest.Assert(t, err.Error(), "'not_exist' is not a valid id of a PWM pin") + assert.ErrorContains(t, err, "'not_exist' is not a valid id of a PWM pin") } func Test_PWMPin(t *testing.T) { translateErr := "translator_error" translator := func(string) (string, int, error) { return pwmDir, 44, nil } - var tests = map[string]struct { + tests := map[string]struct { mockPaths []string period string + dutyCycle string translate func(string) (string, int, error) pin string wantErr string }{ "pin_ok": { mockPaths: []string{pwmExportPath, pwmEnablePath, pwmPeriodPath, pwmDutyCyclePath, pwmPolarityPath}, + period: "0", + dutyCycle: "0", translate: translator, pin: "33", }, @@ -293,18 +301,23 @@ func Test_PWMPin(t *testing.T) { wantErr: "SetEnabled(false) failed for id 44 with : /sys/devices/platform/ff680020.pwm/pwm/pwmchip3/pwm44/enable: no such file", }, "init_setperiod_dutycycle_no_error": { - mockPaths: []string{pwmExportPath, pwmEnablePath, pwmPeriodPath, pwmPolarityPath}, + mockPaths: []string{pwmExportPath, pwmEnablePath, pwmPeriodPath, pwmDutyCyclePath, pwmPolarityPath}, + period: "0", + dutyCycle: "0", translate: translator, pin: "33", }, "init_setperiod_error": { - mockPaths: []string{pwmExportPath, pwmEnablePath}, + mockPaths: []string{pwmExportPath, pwmEnablePath, pwmDutyCyclePath}, + dutyCycle: "0", translate: translator, pin: "33", wantErr: "SetPeriod(10000000) failed for id 44 with : /sys/devices/platform/ff680020.pwm/pwm/pwmchip3/pwm44/period: no such file", }, "init_setpolarity_error": { mockPaths: []string{pwmExportPath, pwmEnablePath, pwmPeriodPath, pwmDutyCyclePath}, + period: "0", + dutyCycle: "0", translate: translator, pin: "33", wantErr: "SetPolarity(normal) failed for id 44 with : /sys/devices/platform/ff680020.pwm/pwm/pwmchip3/pwm44/polarity: no such file", @@ -322,6 +335,9 @@ func Test_PWMPin(t *testing.T) { if tc.period != "" { fs.Files[pwmPeriodPath].Contents = tc.period } + if tc.dutyCycle != "" { + fs.Files[pwmDutyCyclePath].Contents = tc.dutyCycle + } a := NewPWMPinsAdaptor(sys, tc.translate) if err := a.Connect(); err != nil { panic(err) @@ -330,13 +346,15 @@ func Test_PWMPin(t *testing.T) { got, err := a.PWMPin(tc.pin) // assert if tc.wantErr == "" { - gobottest.Assert(t, err, nil) - gobottest.Refute(t, got, nil) + assert.NoError(t, err) + assert.NotNil(t, got) } else { - gobottest.Assert(t, strings.Contains(err.Error(), tc.wantErr), true) - gobottest.Assert(t, got, nil) + if !strings.Contains(err.Error(), tc.wantErr) { + log.Println(err.Error()) + } + assert.Contains(t, err.Error(), tc.wantErr) + assert.Nil(t, got) } - }) } } diff --git a/platforms/adaptors/spibusadaptor.go b/platforms/adaptors/spibusadaptor.go index 12e6acf00..55608300a 100644 --- a/platforms/adaptors/spibusadaptor.go +++ b/platforms/adaptors/spibusadaptor.go @@ -27,7 +27,8 @@ type SpiBusAdaptor struct { // NewSpiBusAdaptor provides the access to SPI buses of the board. The validator is used to check the // bus number (given by user) to the abilities of the board. func NewSpiBusAdaptor(sys *system.Accesser, v spiBusNumberValidator, busNum, chipNum, mode, bits int, - maxSpeed int64) *SpiBusAdaptor { + maxSpeed int64, +) *SpiBusAdaptor { a := &SpiBusAdaptor{ sys: sys, validateBusNumber: v, diff --git a/platforms/adaptors/spibusadaptor_test.go b/platforms/adaptors/spibusadaptor_test.go index 14c91c0b8..1b0f0d7d2 100644 --- a/platforms/adaptors/spibusadaptor_test.go +++ b/platforms/adaptors/spibusadaptor_test.go @@ -2,11 +2,10 @@ package adaptors import ( "fmt" - "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2/drivers/spi" - "gobot.io/x/gobot/v2/gobottest" "gobot.io/x/gobot/v2/system" ) @@ -35,13 +34,13 @@ func TestNewSpiAdaptor(t *testing.T) { // arrange a := NewSpiBusAdaptor(nil, nil, 1, 2, 3, 4, 5) // act & assert - gobottest.Assert(t, a.SpiDefaultBusNumber(), 1) - gobottest.Assert(t, a.SpiDefaultChipNumber(), 2) - gobottest.Assert(t, a.SpiDefaultMode(), 3) - gobottest.Assert(t, a.SpiDefaultBitCount(), 4) - gobottest.Assert(t, a.SpiDefaultMaxSpeed(), int64(5)) + assert.Equal(t, 1, a.SpiDefaultBusNumber()) + assert.Equal(t, 2, a.SpiDefaultChipNumber()) + assert.Equal(t, 3, a.SpiDefaultMode()) + assert.Equal(t, 4, a.SpiDefaultBitCount()) + assert.Equal(t, int64(5), a.SpiDefaultMaxSpeed()) _, err := a.GetSpiConnection(10, 0, 0, 8, 10000000) - gobottest.Assert(t, err.Error(), "not connected") + assert.ErrorContains(t, err, "not connected") } func TestGetSpiConnection(t *testing.T) { @@ -54,67 +53,67 @@ func TestGetSpiConnection(t *testing.T) { maxSpeed = int64(11) ) a, spi := initTestSpiBusAdaptorWithMockedSpi() - gobottest.Assert(t, len(a.connections), 0) + assert.Equal(t, 0, len(a.connections)) // act con1, err1 := a.GetSpiConnection(busNum, chipNum, mode, bits, maxSpeed) // assert - gobottest.Assert(t, err1, nil) - gobottest.Refute(t, con1, nil) - gobottest.Assert(t, len(a.connections), 1) + assert.NoError(t, err1) + assert.NotNil(t, con1) + assert.Equal(t, 1, len(a.connections)) // assert cached connection con1a, err2 := a.GetSpiConnection(busNum, chipNum, mode, bits, maxSpeed) - gobottest.Assert(t, err2, nil) - gobottest.Assert(t, con1a, con1) - gobottest.Assert(t, len(a.connections), 1) + assert.NoError(t, err2) + assert.Equal(t, con1, con1a) + assert.Equal(t, 1, len(a.connections)) // assert second connection con2, err3 := a.GetSpiConnection(busNum, chipNum+1, mode, bits, maxSpeed) - gobottest.Assert(t, err3, nil) - gobottest.Refute(t, con2, nil) - gobottest.Refute(t, con2, con1) - gobottest.Assert(t, len(a.connections), 2) + assert.NoError(t, err3) + assert.NotNil(t, con2) + assert.NotEqual(t, con1, con2) + assert.Equal(t, 2, len(a.connections)) // assert bus validation error con, err := a.GetSpiConnection(busNum+1, chipNum, mode, bits, maxSpeed) - gobottest.Assert(t, err.Error(), "16 not valid") - gobottest.Assert(t, con, nil) + assert.ErrorContains(t, err, "16 not valid") + assert.Nil(t, con) // assert create error spi.CreateError = true con, err = a.GetSpiConnection(busNum, chipNum+2, mode, bits, maxSpeed) - gobottest.Assert(t, err.Error(), "error while create SPI connection in mock") - gobottest.Assert(t, con, nil) + assert.ErrorContains(t, err, "error while create SPI connection in mock") + assert.Nil(t, con) } func TestSpiFinalize(t *testing.T) { // arrange a, _ := initTestSpiBusAdaptorWithMockedSpi() _, e := a.GetSpiConnection(spiTestAllowedBus, 2, 3, 4, 5) - gobottest.Assert(t, e, nil) - gobottest.Assert(t, len(a.connections), 1) + assert.NoError(t, e) + assert.Equal(t, 1, len(a.connections)) // act err := a.Finalize() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.connections), 0) + assert.NoError(t, err) + assert.Equal(t, 0, len(a.connections)) } func TestSpiFinalizeWithError(t *testing.T) { // arrange a, spi := initTestSpiBusAdaptorWithMockedSpi() _, e := a.GetSpiConnection(spiTestAllowedBus, 2, 3, 4, 5) - gobottest.Assert(t, e, nil) + assert.NoError(t, e) spi.SetCloseError(true) // act err := a.Finalize() // assert - gobottest.Assert(t, strings.Contains(err.Error(), "error while SPI close"), true) + assert.Contains(t, err.Error(), "error while SPI close") } func TestSpiReConnect(t *testing.T) { // arrange a, _ := initTestSpiBusAdaptorWithMockedSpi() - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) // act - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) // assert - gobottest.Refute(t, a.connections, nil) - gobottest.Assert(t, len(a.connections), 0) + assert.NotNil(t, a.connections) + assert.Equal(t, 0, len(a.connections)) } diff --git a/platforms/audio/audio_adaptor_test.go b/platforms/audio/audio_adaptor_test.go index f03326b22..823cce510 100644 --- a/platforms/audio/audio_adaptor_test.go +++ b/platforms/audio/audio_adaptor_test.go @@ -2,12 +2,13 @@ package audio import ( + "os" "os/exec" "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Adaptor = (*Adaptor)(nil) @@ -15,54 +16,62 @@ var _ gobot.Adaptor = (*Adaptor)(nil) func TestAudioAdaptor(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, a.Connect(), nil) - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Connect()) + assert.NoError(t, a.Finalize()) } func TestAudioAdaptorName(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, strings.HasPrefix(a.Name(), "Audio"), true) + assert.True(t, strings.HasPrefix(a.Name(), "Audio")) a.SetName("NewName") - gobottest.Assert(t, a.Name(), "NewName") + assert.Equal(t, "NewName", a.Name()) } func TestAudioAdaptorCommandsWav(t *testing.T) { cmd, _ := CommandName("whatever.wav") - gobottest.Assert(t, cmd, "aplay") + assert.Equal(t, "aplay", cmd) } func TestAudioAdaptorCommandsMp3(t *testing.T) { cmd, _ := CommandName("whatever.mp3") - gobottest.Assert(t, cmd, "mpg123") + assert.Equal(t, "mpg123", cmd) } func TestAudioAdaptorCommandsUnknown(t *testing.T) { cmd, err := CommandName("whatever.unk") - gobottest.Refute(t, cmd, "mpg123") - gobottest.Assert(t, err.Error(), "Unknown filetype for audio file.") + assert.NotEqual(t, "mpg123", cmd) + assert.ErrorContains(t, err, "Unknown filetype for audio file.") } func TestAudioAdaptorSoundWithNoFilename(t *testing.T) { a := NewAdaptor() errors := a.Sound("") - gobottest.Assert(t, errors[0].Error(), "Requires filename for audio file.") + assert.Equal(t, "Requires filename for audio file.", errors[0].Error()) } func TestAudioAdaptorSoundWithNonexistingFilename(t *testing.T) { a := NewAdaptor() errors := a.Sound("doesnotexist.mp3") - gobottest.Assert(t, errors[0].Error(), "stat doesnotexist.mp3: no such file or directory") + assert.Equal(t, "stat doesnotexist.mp3: no such file or directory", errors[0].Error()) } func TestAudioAdaptorSoundWithValidMP3Filename(t *testing.T) { - execCommand = gobottest.ExecCommand + execCommand = myExecCommand a := NewAdaptor() defer func() { execCommand = exec.Command }() errors := a.Sound("../../examples/laser.mp3") - gobottest.Assert(t, len(errors), 0) + assert.Equal(t, 0, len(errors)) +} + +func myExecCommand(command string, args ...string) *exec.Cmd { + cs := []string{"-test.run=TestHelperProcess", "--", command} + cs = append(cs, args...) + cmd := exec.Command(os.Args[0], cs...) //nolint:gosec // ok for test + cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"} + return cmd } diff --git a/platforms/audio/audio_driver_test.go b/platforms/audio/audio_driver_test.go index c9cba850f..cf5de2195 100644 --- a/platforms/audio/audio_driver_test.go +++ b/platforms/audio/audio_driver_test.go @@ -7,8 +7,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*Driver)(nil) @@ -16,35 +16,35 @@ var _ gobot.Driver = (*Driver)(nil) func TestAudioDriver(t *testing.T) { d := NewDriver(NewAdaptor(), "../../examples/laser.mp3") - gobottest.Assert(t, d.Filename(), "../../examples/laser.mp3") + assert.Equal(t, "../../examples/laser.mp3", d.Filename()) - gobottest.Refute(t, d.Connection(), nil) + assert.NotNil(t, d.Connection()) - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestAudioDriverName(t *testing.T) { d := NewDriver(NewAdaptor(), "") - gobottest.Assert(t, strings.HasPrefix(d.Name(), "Audio"), true) + assert.True(t, strings.HasPrefix(d.Name(), "Audio")) d.SetName("NewName") - gobottest.Assert(t, d.Name(), "NewName") + assert.Equal(t, "NewName", d.Name()) } func TestAudioDriverSoundWithNoFilename(t *testing.T) { d := NewDriver(NewAdaptor(), "") errors := d.Sound("") - gobottest.Assert(t, errors[0].Error(), "Requires filename for audio file.") + assert.Equal(t, "Requires filename for audio file.", errors[0].Error()) } func TestAudioDriverSoundWithDefaultFilename(t *testing.T) { - execCommand = gobottest.ExecCommand + execCommand = myExecCommand defer func() { execCommand = exec.Command }() d := NewDriver(NewAdaptor(), "../../examples/laser.mp3") errors := d.Play() - gobottest.Assert(t, len(errors), 0) + assert.Equal(t, 0, len(errors)) } diff --git a/platforms/beaglebone/README.md b/platforms/beaglebone/README.md index c07c1f4aa..ea871af24 100644 --- a/platforms/beaglebone/README.md +++ b/platforms/beaglebone/README.md @@ -110,7 +110,7 @@ scp beaglebone_blink debian@192.168.7.2:/home/debian/ ssh -t debian@192.168.7.2 "./beaglebone_blink" ``` -In order to run the preceeding commands, you must be running the official Debian Linux through the usb->ethernet connection, +In order to run the preceding commands, you must be running the official Debian Linux through the usb->ethernet connection, or be connected to the board using WiFi. You must also configure hardware settings as described below. diff --git a/platforms/beaglebone/beaglebone_adaptor.go b/platforms/beaglebone/beaglebone_adaptor.go index c208f9fa6..2486b9cf2 100644 --- a/platforms/beaglebone/beaglebone_adaptor.go +++ b/platforms/beaglebone/beaglebone_adaptor.go @@ -127,7 +127,7 @@ func (c *Adaptor) DigitalWrite(id string, val byte) error { defer c.mutex.Unlock() if strings.Contains(id, "usr") { - fi, e := c.sys.OpenFile(c.usrLed+id+"/brightness", os.O_WRONLY|os.O_APPEND, 0666) + fi, e := c.sys.OpenFile(c.usrLed+id+"/brightness", os.O_WRONLY|os.O_APPEND, 0o666) defer fi.Close() //nolint:staticcheck // for historical reasons if e != nil { return e @@ -145,14 +145,14 @@ func (c *Adaptor) AnalogRead(pin string) (val int, err error) { if err != nil { return } - fi, err := c.sys.OpenFile(fmt.Sprintf("%v/%v", c.analogPath, analogPin), os.O_RDONLY, 0644) + fi, err := c.sys.OpenFile(fmt.Sprintf("%v/%v", c.analogPath, analogPin), os.O_RDONLY, 0o644) defer fi.Close() //nolint:staticcheck // for historical reasons if err != nil { return } - var buf = make([]byte, 1024) + buf := make([]byte, 1024) _, err = fi.Read(buf) if err != nil { return @@ -238,7 +238,7 @@ func (p pwmPinData) findPWMDir(sys *system.Accesser) (dir string, err error) { func (c *Adaptor) muxPin(pin, cmd string) error { path := fmt.Sprintf("/sys/devices/platform/ocp/ocp:%s_pinmux/state", pin) - fi, e := c.sys.OpenFile(path, os.O_WRONLY, 0666) + fi, e := c.sys.OpenFile(path, os.O_WRONLY, 0o666) defer fi.Close() //nolint:staticcheck // for historical reasons if e != nil { return e diff --git a/platforms/beaglebone/beaglebone_adaptor_test.go b/platforms/beaglebone/beaglebone_adaptor_test.go index ed5e5a38f..c7bf5a487 100644 --- a/platforms/beaglebone/beaglebone_adaptor_test.go +++ b/platforms/beaglebone/beaglebone_adaptor_test.go @@ -1,31 +1,32 @@ package beaglebone import ( - "errors" "fmt" "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" "gobot.io/x/gobot/v2/drivers/aio" "gobot.io/x/gobot/v2/drivers/gpio" "gobot.io/x/gobot/v2/drivers/i2c" "gobot.io/x/gobot/v2/drivers/spi" - "gobot.io/x/gobot/v2/gobottest" "gobot.io/x/gobot/v2/system" ) // make sure that this Adaptor fulfills all the required interfaces -var _ gobot.Adaptor = (*Adaptor)(nil) -var _ gobot.DigitalPinnerProvider = (*Adaptor)(nil) -var _ gobot.PWMPinnerProvider = (*Adaptor)(nil) -var _ gpio.DigitalReader = (*Adaptor)(nil) -var _ gpio.DigitalWriter = (*Adaptor)(nil) -var _ aio.AnalogReader = (*Adaptor)(nil) -var _ gpio.PwmWriter = (*Adaptor)(nil) -var _ gpio.ServoWriter = (*Adaptor)(nil) -var _ i2c.Connector = (*Adaptor)(nil) -var _ spi.Connector = (*Adaptor)(nil) +var ( + _ gobot.Adaptor = (*Adaptor)(nil) + _ gobot.DigitalPinnerProvider = (*Adaptor)(nil) + _ gobot.PWMPinnerProvider = (*Adaptor)(nil) + _ gpio.DigitalReader = (*Adaptor)(nil) + _ gpio.DigitalWriter = (*Adaptor)(nil) + _ aio.AnalogReader = (*Adaptor)(nil) + _ gpio.PwmWriter = (*Adaptor)(nil) + _ gpio.ServoWriter = (*Adaptor)(nil) + _ i2c.Connector = (*Adaptor)(nil) + _ spi.Connector = (*Adaptor)(nil) +) func initTestAdaptorWithMockedFilesystem(mockPaths []string) (*Adaptor, *system.MockFilesystem) { a := NewAdaptor() @@ -54,33 +55,35 @@ func TestPWM(t *testing.T) { } a, fs := initTestAdaptorWithMockedFilesystem(mockPaths) + fs.Files["/sys/devices/platform/ocp/48300000.epwmss/48300200.pwm/pwm/pwmchip0/pwm1/duty_cycle"].Contents = "0" + fs.Files["/sys/devices/platform/ocp/48300000.epwmss/48300200.pwm/pwm/pwmchip0/pwm1/period"].Contents = "0" - gobottest.Assert(t, a.PwmWrite("P9_99", 175), errors.New("'P9_99' is not a valid id for a PWM pin")) + assert.ErrorContains(t, a.PwmWrite("P9_99", 175), "'P9_99' is not a valid id for a PWM pin") _ = a.PwmWrite("P9_21", 175) - gobottest.Assert( + assert.Equal( t, - fs.Files["/sys/devices/platform/ocp/48300000.epwmss/48300200.pwm/pwm/pwmchip0/pwm1/period"].Contents, "500000", + fs.Files["/sys/devices/platform/ocp/48300000.epwmss/48300200.pwm/pwm/pwmchip0/pwm1/period"].Contents, ) - gobottest.Assert( + assert.Equal( t, - fs.Files["/sys/devices/platform/ocp/48300000.epwmss/48300200.pwm/pwm/pwmchip0/pwm1/duty_cycle"].Contents, "343137", + fs.Files["/sys/devices/platform/ocp/48300000.epwmss/48300200.pwm/pwm/pwmchip0/pwm1/duty_cycle"].Contents, ) _ = a.ServoWrite("P9_21", 100) - gobottest.Assert( + assert.Equal( t, - fs.Files["/sys/devices/platform/ocp/48300000.epwmss/48300200.pwm/pwm/pwmchip0/pwm1/period"].Contents, "500000", + fs.Files["/sys/devices/platform/ocp/48300000.epwmss/48300200.pwm/pwm/pwmchip0/pwm1/period"].Contents, ) - gobottest.Assert( + assert.Equal( t, - fs.Files["/sys/devices/platform/ocp/48300000.epwmss/48300200.pwm/pwm/pwmchip0/pwm1/duty_cycle"].Contents, "66666", + fs.Files["/sys/devices/platform/ocp/48300000.epwmss/48300200.pwm/pwm/pwmchip0/pwm1/duty_cycle"].Contents, ) - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) } func TestAnalog(t *testing.T) { @@ -92,18 +95,18 @@ func TestAnalog(t *testing.T) { fs.Files["/sys/bus/iio/devices/iio:device0/in_voltage1_raw"].Contents = "567\n" i, err := a.AnalogRead("P9_40") - gobottest.Assert(t, i, 567) - gobottest.Assert(t, err, nil) + assert.Equal(t, 567, i) + assert.NoError(t, err) _, err = a.AnalogRead("P9_99") - gobottest.Assert(t, err, errors.New("Not a valid analog pin")) + assert.ErrorContains(t, err, "Not a valid analog pin") fs.WithReadError = true _, err = a.AnalogRead("P9_40") - gobottest.Assert(t, err, errors.New("read error")) + assert.ErrorContains(t, err, "read error") fs.WithReadError = false - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) } func TestDigitalIO(t *testing.T) { @@ -128,36 +131,36 @@ func TestDigitalIO(t *testing.T) { // DigitalIO _ = a.DigitalWrite("usr1", 1) - gobottest.Assert(t, - fs.Files["/sys/class/leds/beaglebone:green:usr1/brightness"].Contents, + assert.Equal(t, "1", + fs.Files["/sys/class/leds/beaglebone:green:usr1/brightness"].Contents, ) // no such LED err := a.DigitalWrite("usr10101", 1) - gobottest.Assert(t, err.Error(), " : /sys/class/leds/beaglebone:green:usr10101/brightness: no such file") + assert.ErrorContains(t, err, " : /sys/class/leds/beaglebone:green:usr10101/brightness: no such file") _ = a.DigitalWrite("P9_12", 1) - gobottest.Assert(t, fs.Files["/sys/class/gpio/gpio60/value"].Contents, "1") + assert.Equal(t, "1", fs.Files["/sys/class/gpio/gpio60/value"].Contents) - gobottest.Assert(t, a.DigitalWrite("P9_99", 1), errors.New("'P9_99' is not a valid id for a digital pin")) + assert.ErrorContains(t, a.DigitalWrite("P9_99", 1), "'P9_99' is not a valid id for a digital pin") _, err = a.DigitalRead("P9_99") - gobottest.Assert(t, err, errors.New("'P9_99' is not a valid id for a digital pin")) + assert.ErrorContains(t, err, "'P9_99' is not a valid id for a digital pin") fs.Files["/sys/class/gpio/gpio66/value"].Contents = "1" i, err := a.DigitalRead("P8_07") - gobottest.Assert(t, i, 1) - gobottest.Assert(t, err, nil) + assert.Equal(t, 1, i) + assert.NoError(t, err) - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) } func TestName(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, strings.HasPrefix(a.Name(), "Beaglebone"), true) + assert.True(t, strings.HasPrefix(a.Name(), "Beaglebone")) a.SetName("NewName") - gobottest.Assert(t, a.Name(), "NewName") + assert.Equal(t, "NewName", a.Name()) } func TestAnalogReadFileError(t *testing.T) { @@ -168,7 +171,7 @@ func TestAnalogReadFileError(t *testing.T) { a, _ := initTestAdaptorWithMockedFilesystem(mockPaths) _, err := a.AnalogRead("P9_40") - gobottest.Assert(t, strings.Contains(err.Error(), "/sys/bus/iio/devices/iio:device0/in_voltage1_raw: no such file"), true) + assert.Contains(t, err.Error(), "/sys/bus/iio/devices/iio:device0/in_voltage1_raw: no such file") } func TestDigitalPinDirectionFileError(t *testing.T) { @@ -181,11 +184,11 @@ func TestDigitalPinDirectionFileError(t *testing.T) { a, _ := initTestAdaptorWithMockedFilesystem(mockPaths) err := a.DigitalWrite("P9_12", 1) - gobottest.Assert(t, strings.Contains(err.Error(), "/sys/class/gpio/gpio60/direction: no such file"), true) + assert.Contains(t, err.Error(), "/sys/class/gpio/gpio60/direction: no such file") // no pin added after previous problem, so no pin to unexport in finalize err = a.Finalize() - gobottest.Assert(t, nil, err) + assert.Equal(t, err, nil) } func TestDigitalPinFinalizeFileError(t *testing.T) { @@ -199,30 +202,30 @@ func TestDigitalPinFinalizeFileError(t *testing.T) { a, _ := initTestAdaptorWithMockedFilesystem(mockPaths) err := a.DigitalWrite("P9_12", 1) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) err = a.Finalize() - gobottest.Assert(t, strings.Contains(err.Error(), "/sys/class/gpio/unexport: no such file"), true) + assert.Contains(t, err.Error(), "/sys/class/gpio/unexport: no such file") } func TestPocketName(t *testing.T) { a := NewPocketBeagleAdaptor() - gobottest.Assert(t, strings.HasPrefix(a.Name(), "PocketBeagle"), true) + assert.True(t, strings.HasPrefix(a.Name(), "PocketBeagle")) } func TestSpiDefaultValues(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, a.SpiDefaultBusNumber(), 0) - gobottest.Assert(t, a.SpiDefaultChipNumber(), 0) - gobottest.Assert(t, a.SpiDefaultMode(), 0) - gobottest.Assert(t, a.SpiDefaultBitCount(), 8) - gobottest.Assert(t, a.SpiDefaultMaxSpeed(), int64(500000)) + assert.Equal(t, 0, a.SpiDefaultBusNumber()) + assert.Equal(t, 0, a.SpiDefaultChipNumber()) + assert.Equal(t, 0, a.SpiDefaultMode()) + assert.Equal(t, 8, a.SpiDefaultBitCount()) + assert.Equal(t, int64(500000), a.SpiDefaultMaxSpeed()) } func TestI2cDefaultBus(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, a.DefaultI2cBus(), 2) + assert.Equal(t, 2, a.DefaultI2cBus()) } func TestI2cFinalizeWithErrors(t *testing.T) { @@ -230,20 +233,20 @@ func TestI2cFinalizeWithErrors(t *testing.T) { a := NewAdaptor() a.sys.UseMockSyscall() fs := a.sys.UseMockFilesystem([]string{"/dev/i2c-2"}) - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) con, err := a.GetI2cConnection(0xff, 2) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) _, err = con.Write([]byte{0xbf}) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) fs.WithCloseError = true // act err = a.Finalize() // assert - gobottest.Assert(t, strings.Contains(err.Error(), "close error"), true) + assert.Contains(t, err.Error(), "close error") } func Test_validateSpiBusNumber(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { busNr int wantErr error }{ @@ -269,13 +272,13 @@ func Test_validateSpiBusNumber(t *testing.T) { // act err := a.validateSpiBusNumber(tc.busNr) // assert - gobottest.Assert(t, err, tc.wantErr) + assert.Equal(t, tc.wantErr, err) }) } } func Test_validateI2cBusNumber(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { busNr int wantErr error }{ @@ -305,7 +308,7 @@ func Test_validateI2cBusNumber(t *testing.T) { // act err := a.validateI2cBusNumber(tc.busNr) // assert - gobottest.Assert(t, err, tc.wantErr) + assert.Equal(t, tc.wantErr, err) }) } } @@ -320,7 +323,7 @@ func Test_translateAndMuxPWMPin(t *testing.T) { } a, fs := initTestAdaptorWithMockedFilesystem(mockPaths) - var tests = map[string]struct { + tests := map[string]struct { wantDir string wantChannel int wantErr error @@ -367,11 +370,11 @@ func Test_translateAndMuxPWMPin(t *testing.T) { // act path, channel, err := a.translateAndMuxPWMPin(name) // assert - gobottest.Assert(t, err, tc.wantErr) - gobottest.Assert(t, path, tc.wantDir) - gobottest.Assert(t, channel, tc.wantChannel) + assert.Equal(t, tc.wantErr, err) + assert.Equal(t, tc.wantDir, path) + assert.Equal(t, tc.wantChannel, channel) if tc.wantErr == nil { - gobottest.Assert(t, fs.Files[muxPath].Contents, "pwm") + assert.Equal(t, "pwm", fs.Files[muxPath].Contents) } }) } diff --git a/platforms/ble/battery_driver.go b/platforms/ble/battery_driver.go index 0366a63d6..fc38e7262 100644 --- a/platforms/ble/battery_driver.go +++ b/platforms/ble/battery_driver.go @@ -57,6 +57,6 @@ func (b *BatteryDriver) GetBatteryLevel() (level uint8) { } buf := bytes.NewBuffer(c) val, _ := buf.ReadByte() - l = uint8(val) + l = val return l } diff --git a/platforms/ble/battery_driver_test.go b/platforms/ble/battery_driver_test.go index 8ba4e42dc..8280d8a1c 100644 --- a/platforms/ble/battery_driver_test.go +++ b/platforms/ble/battery_driver_test.go @@ -4,8 +4,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*BatteryDriver)(nil) @@ -17,15 +17,15 @@ func initTestBatteryDriver() *BatteryDriver { func TestBatteryDriver(t *testing.T) { d := initTestBatteryDriver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "Battery"), true) + assert.True(t, strings.HasPrefix(d.Name(), "Battery")) d.SetName("NewName") - gobottest.Assert(t, d.Name(), "NewName") + assert.Equal(t, "NewName", d.Name()) } func TestBatteryDriverStartAndHalt(t *testing.T) { d := initTestBatteryDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Halt()) } func TestBatteryDriverRead(t *testing.T) { @@ -35,5 +35,5 @@ func TestBatteryDriverRead(t *testing.T) { return []byte{20}, nil }) - gobottest.Assert(t, d.GetBatteryLevel(), uint8(20)) + assert.Equal(t, uint8(20), d.GetBatteryLevel()) } diff --git a/platforms/ble/ble_client_adaptor.go b/platforms/ble/ble_client_adaptor.go index ce65c3807..8af9419dc 100644 --- a/platforms/ble/ble_client_adaptor.go +++ b/platforms/ble/ble_client_adaptor.go @@ -11,8 +11,10 @@ import ( "tinygo.org/x/bluetooth" ) -var currentAdapter *bluetooth.Adapter -var bleMutex sync.Mutex +var ( + currentAdapter *bluetooth.Adapter + bleMutex sync.Mutex +) // BLEConnector is the interface that a BLE ClientAdaptor must implement type BLEConnector interface { @@ -212,7 +214,7 @@ func (b *ClientAdaptor) Subscribe(cUUID string, f func([]byte, error)) error { } // getBLEAdapter is singleton for bluetooth adapter connection -func getBLEAdapter(impl string) (*bluetooth.Adapter, error) { +func getBLEAdapter(impl string) (*bluetooth.Adapter, error) { //nolint:unparam // TODO: impl is unused, maybe an error if currentAdapter != nil { return currentAdapter, nil } diff --git a/platforms/ble/ble_client_adaptor_test.go b/platforms/ble/ble_client_adaptor_test.go index 59bd8e981..96fb233f1 100644 --- a/platforms/ble/ble_client_adaptor_test.go +++ b/platforms/ble/ble_client_adaptor_test.go @@ -4,20 +4,20 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Adaptor = (*ClientAdaptor)(nil) func TestBLEClientAdaptor(t *testing.T) { a := NewClientAdaptor("D7:99:5A:26:EC:38") - gobottest.Assert(t, a.Address(), "D7:99:5A:26:EC:38") - gobottest.Assert(t, strings.HasPrefix(a.Name(), "BLEClient"), true) + assert.Equal(t, "D7:99:5A:26:EC:38", a.Address()) + assert.True(t, strings.HasPrefix(a.Name(), "BLEClient")) } func TestBLEClientAdaptorName(t *testing.T) { a := NewClientAdaptor("D7:99:5A:26:EC:38") a.SetName("awesome") - gobottest.Assert(t, a.Name(), "awesome") + assert.Equal(t, "awesome", a.Name()) } diff --git a/platforms/ble/device_information_driver_test.go b/platforms/ble/device_information_driver_test.go index 81d6f333a..1a8234c51 100644 --- a/platforms/ble/device_information_driver_test.go +++ b/platforms/ble/device_information_driver_test.go @@ -4,8 +4,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*DeviceInformationDriver)(nil) @@ -17,15 +17,15 @@ func initTestDeviceInformationDriver() *DeviceInformationDriver { func TestDeviceInformationDriver(t *testing.T) { d := initTestDeviceInformationDriver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "DeviceInformation"), true) + assert.True(t, strings.HasPrefix(d.Name(), "DeviceInformation")) d.SetName("NewName") - gobottest.Assert(t, d.Name(), "NewName") + assert.Equal(t, "NewName", d.Name()) } func TestDeviceInformationDriverStartAndHalt(t *testing.T) { d := initTestDeviceInformationDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Halt()) } func TestDeviceInformationDriverGetModelNumber(t *testing.T) { @@ -35,7 +35,7 @@ func TestDeviceInformationDriverGetModelNumber(t *testing.T) { return []byte("TestDevice"), nil }) - gobottest.Assert(t, d.GetModelNumber(), "TestDevice") + assert.Equal(t, "TestDevice", d.GetModelNumber()) } func TestDeviceInformationDriverGetFirmwareRevision(t *testing.T) { @@ -45,7 +45,7 @@ func TestDeviceInformationDriverGetFirmwareRevision(t *testing.T) { return []byte("TestDevice"), nil }) - gobottest.Assert(t, d.GetFirmwareRevision(), "TestDevice") + assert.Equal(t, "TestDevice", d.GetFirmwareRevision()) } func TestDeviceInformationDriverGetHardwareRevision(t *testing.T) { @@ -55,7 +55,7 @@ func TestDeviceInformationDriverGetHardwareRevision(t *testing.T) { return []byte("TestDevice"), nil }) - gobottest.Assert(t, d.GetHardwareRevision(), "TestDevice") + assert.Equal(t, "TestDevice", d.GetHardwareRevision()) } func TestDeviceInformationDriverGetManufacturerName(t *testing.T) { @@ -65,7 +65,7 @@ func TestDeviceInformationDriverGetManufacturerName(t *testing.T) { return []byte("TestDevice"), nil }) - gobottest.Assert(t, d.GetManufacturerName(), "TestDevice") + assert.Equal(t, "TestDevice", d.GetManufacturerName()) } func TestDeviceInformationDriverGetPnPId(t *testing.T) { @@ -75,5 +75,5 @@ func TestDeviceInformationDriverGetPnPId(t *testing.T) { return []byte("TestDevice"), nil }) - gobottest.Assert(t, d.GetPnPId(), "TestDevice") + assert.Equal(t, "TestDevice", d.GetPnPId()) } diff --git a/platforms/ble/generic_access_driver_test.go b/platforms/ble/generic_access_driver_test.go index 18dcbf098..8c5c90120 100644 --- a/platforms/ble/generic_access_driver_test.go +++ b/platforms/ble/generic_access_driver_test.go @@ -4,8 +4,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*GenericAccessDriver)(nil) @@ -17,15 +17,15 @@ func initTestGenericAccessDriver() *GenericAccessDriver { func TestGenericAccessDriver(t *testing.T) { d := initTestGenericAccessDriver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "GenericAccess"), true) + assert.True(t, strings.HasPrefix(d.Name(), "GenericAccess")) d.SetName("NewName") - gobottest.Assert(t, d.Name(), "NewName") + assert.Equal(t, "NewName", d.Name()) } func TestGenericAccessDriverStartAndHalt(t *testing.T) { d := initTestGenericAccessDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Halt()) } func TestGenericAccessDriverGetDeviceName(t *testing.T) { @@ -35,7 +35,7 @@ func TestGenericAccessDriverGetDeviceName(t *testing.T) { return []byte("TestDevice"), nil }) - gobottest.Assert(t, d.GetDeviceName(), "TestDevice") + assert.Equal(t, "TestDevice", d.GetDeviceName()) } func TestGenericAccessDriverGetAppearance(t *testing.T) { @@ -45,5 +45,5 @@ func TestGenericAccessDriverGetAppearance(t *testing.T) { return []byte{128, 0}, nil }) - gobottest.Assert(t, d.GetAppearance(), "Generic Computer") + assert.Equal(t, "Generic Computer", d.GetAppearance()) } diff --git a/platforms/ble/serial_port_test.go b/platforms/ble/serial_port_test.go index fe2bebb6d..47dc87cdb 100644 --- a/platforms/ble/serial_port_test.go +++ b/platforms/ble/serial_port_test.go @@ -3,7 +3,7 @@ package ble import ( "testing" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) func initTestBLESerialPort() *SerialPort { @@ -12,5 +12,5 @@ func initTestBLESerialPort() *SerialPort { func TestBLESerialPort(t *testing.T) { d := initTestBLESerialPort() - gobottest.Assert(t, d.Address(), "TEST123") + assert.Equal(t, "TEST123", d.Address()) } diff --git a/platforms/chip/README.md b/platforms/chip/README.md index 4b62bbc83..40f6e79ce 100644 --- a/platforms/chip/README.md +++ b/platforms/chip/README.md @@ -40,43 +40,8 @@ Reboot the device to make sure the init script loads the overlay on boot. ## How to Use +Please refer to one example for your platform, e.g. [chip_button.go](https://github.com/hybridgroup/gobot/blob/release/examples/chip_button.go). The pin numbering used by your Gobot program should match the way your board is labeled right on the board itself. - -```go -package main - -import ( - "fmt" - - "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/drivers/gpio" - "gobot.io/x/gobot/v2/platforms/chip" -) - -func main() { - chipAdaptor := chip.NewAdaptor() - button := gpio.NewButtonDriver(chipAdaptor, "XIO-P0") - - work := func() { - gobot.On(button.Event("push"), func(data interface{}) { - fmt.Println("button pressed") - }) - - gobot.On(button.Event("release"), func(data interface{}) { - fmt.Println("button released") - }) - } - - robot := gobot.NewRobot("buttonBot", - []gobot.Connection{chipAdaptor}, - []gobot.Device{button}, - work, - ) - - robot.Start() -} -``` - If you want to use the C.H.I.P. Pro, use the `NewProAdaptor()` function like this: ```go diff --git a/platforms/chip/chip_adaptor_test.go b/platforms/chip/chip_adaptor_test.go index 612b22164..b5710e218 100644 --- a/platforms/chip/chip_adaptor_test.go +++ b/platforms/chip/chip_adaptor_test.go @@ -1,27 +1,28 @@ package chip import ( - "errors" "fmt" "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" "gobot.io/x/gobot/v2/drivers/gpio" "gobot.io/x/gobot/v2/drivers/i2c" - "gobot.io/x/gobot/v2/gobottest" "gobot.io/x/gobot/v2/system" ) // make sure that this Adaptor fulfills all the required interfaces -var _ gobot.Adaptor = (*Adaptor)(nil) -var _ gobot.DigitalPinnerProvider = (*Adaptor)(nil) -var _ gobot.PWMPinnerProvider = (*Adaptor)(nil) -var _ gpio.DigitalReader = (*Adaptor)(nil) -var _ gpio.DigitalWriter = (*Adaptor)(nil) -var _ gpio.PwmWriter = (*Adaptor)(nil) -var _ gpio.ServoWriter = (*Adaptor)(nil) -var _ i2c.Connector = (*Adaptor)(nil) +var ( + _ gobot.Adaptor = (*Adaptor)(nil) + _ gobot.DigitalPinnerProvider = (*Adaptor)(nil) + _ gobot.PWMPinnerProvider = (*Adaptor)(nil) + _ gpio.DigitalReader = (*Adaptor)(nil) + _ gpio.DigitalWriter = (*Adaptor)(nil) + _ gpio.PwmWriter = (*Adaptor)(nil) + _ gpio.ServoWriter = (*Adaptor)(nil) + _ i2c.Connector = (*Adaptor)(nil) +) var mockPaths = []string{ "/sys/class/gpio/export", @@ -58,36 +59,39 @@ func initTestProAdaptorWithMockedFilesystem() (*Adaptor, *system.MockFilesystem) func TestName(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, strings.HasPrefix(a.Name(), "CHIP"), true) + assert.True(t, strings.HasPrefix(a.Name(), "CHIP")) a.SetName("NewName") - gobottest.Assert(t, a.Name(), "NewName") + assert.Equal(t, "NewName", a.Name()) } func TestNewProAdaptor(t *testing.T) { a := NewProAdaptor() - gobottest.Assert(t, strings.HasPrefix(a.Name(), "CHIP Pro"), true) + assert.True(t, strings.HasPrefix(a.Name(), "CHIP Pro")) } func TestFinalizeErrorAfterGPIO(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem() - gobottest.Assert(t, a.Connect(), nil) - gobottest.Assert(t, a.DigitalWrite("CSID7", 1), nil) + assert.NoError(t, a.Connect()) + assert.NoError(t, a.DigitalWrite("CSID7", 1)) fs.WithWriteError = true err := a.Finalize() - gobottest.Assert(t, strings.Contains(err.Error(), "write error"), true) + assert.Contains(t, err.Error(), "write error") } func TestFinalizeErrorAfterPWM(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem() - gobottest.Assert(t, a.Connect(), nil) - gobottest.Assert(t, a.PwmWrite("PWM0", 100), nil) + fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents = "0" + fs.Files["/sys/class/pwm/pwmchip0/pwm0/period"].Contents = "0" + + assert.NoError(t, a.Connect()) + assert.NoError(t, a.PwmWrite("PWM0", 100)) fs.WithWriteError = true err := a.Finalize() - gobottest.Assert(t, strings.Contains(err.Error(), "write error"), true) + assert.Contains(t, err.Error(), "write error") } func TestDigitalIO(t *testing.T) { @@ -95,14 +99,14 @@ func TestDigitalIO(t *testing.T) { _ = a.Connect() _ = a.DigitalWrite("CSID7", 1) - gobottest.Assert(t, fs.Files["/sys/class/gpio/gpio139/value"].Contents, "1") + assert.Equal(t, "1", fs.Files["/sys/class/gpio/gpio139/value"].Contents) fs.Files["/sys/class/gpio/gpio50/value"].Contents = "1" i, _ := a.DigitalRead("TWI2-SDA") - gobottest.Assert(t, i, 1) + assert.Equal(t, 1, i) - gobottest.Assert(t, a.DigitalWrite("XIO-P10", 1), errors.New("'XIO-P10' is not a valid id for a digital pin")) - gobottest.Assert(t, a.Finalize(), nil) + assert.ErrorContains(t, a.DigitalWrite("XIO-P10", 1), "'XIO-P10' is not a valid id for a digital pin") + assert.NoError(t, a.Finalize()) } func TestProDigitalIO(t *testing.T) { @@ -110,43 +114,50 @@ func TestProDigitalIO(t *testing.T) { _ = a.Connect() _ = a.DigitalWrite("CSID7", 1) - gobottest.Assert(t, fs.Files["/sys/class/gpio/gpio139/value"].Contents, "1") + assert.Equal(t, "1", fs.Files["/sys/class/gpio/gpio139/value"].Contents) fs.Files["/sys/class/gpio/gpio50/value"].Contents = "1" i, _ := a.DigitalRead("TWI2-SDA") - gobottest.Assert(t, i, 1) + assert.Equal(t, 1, i) - gobottest.Assert(t, a.DigitalWrite("XIO-P0", 1), errors.New("'XIO-P0' is not a valid id for a digital pin")) - gobottest.Assert(t, a.Finalize(), nil) + assert.ErrorContains(t, a.DigitalWrite("XIO-P0", 1), "'XIO-P0' is not a valid id for a digital pin") + assert.NoError(t, a.Finalize()) } func TestPWM(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem() + fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents = "0" + fs.Files["/sys/class/pwm/pwmchip0/pwm0/period"].Contents = "0" + _ = a.Connect() err := a.PwmWrite("PWM0", 100) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) - gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/export"].Contents, "0") - gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm0/enable"].Contents, "1") - gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents, "3921568") - gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm0/polarity"].Contents, "normal") + assert.Equal(t, "0", fs.Files["/sys/class/pwm/pwmchip0/export"].Contents) + assert.Equal(t, "1", fs.Files["/sys/class/pwm/pwmchip0/pwm0/enable"].Contents) + assert.Equal(t, "3921568", fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents) + assert.Equal(t, "10000000", fs.Files["/sys/class/pwm/pwmchip0/pwm0/period"].Contents) // pwmPeriodDefault + assert.Equal(t, "normal", fs.Files["/sys/class/pwm/pwmchip0/pwm0/polarity"].Contents) err = a.ServoWrite("PWM0", 0) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) - gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents, "500000") + assert.Equal(t, "500000", fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents) + assert.Equal(t, "10000000", fs.Files["/sys/class/pwm/pwmchip0/pwm0/period"].Contents) err = a.ServoWrite("PWM0", 180) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) + + assert.Equal(t, "2000000", fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents) + assert.Equal(t, "10000000", fs.Files["/sys/class/pwm/pwmchip0/pwm0/period"].Contents) // pwmPeriodDefault - gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents, "2000000") - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) } func TestI2cDefaultBus(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, a.DefaultI2cBus(), 1) + assert.Equal(t, 1, a.DefaultI2cBus()) } func TestI2cFinalizeWithErrors(t *testing.T) { @@ -154,20 +165,20 @@ func TestI2cFinalizeWithErrors(t *testing.T) { a := NewAdaptor() a.sys.UseMockSyscall() fs := a.sys.UseMockFilesystem([]string{"/dev/i2c-2"}) - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) con, err := a.GetI2cConnection(0xff, 2) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) _, err = con.Write([]byte{0xbf}) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) fs.WithCloseError = true // act err = a.Finalize() // assert - gobottest.Assert(t, strings.Contains(err.Error(), "close error"), true) + assert.Contains(t, err.Error(), "close error") } func Test_validateI2cBusNumber(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { busNr int wantErr error }{ @@ -196,13 +207,13 @@ func Test_validateI2cBusNumber(t *testing.T) { // act err := a.validateI2cBusNumber(tc.busNr) // assert - gobottest.Assert(t, err, tc.wantErr) + assert.Equal(t, tc.wantErr, err) }) } } func Test_translatePWMPin(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { usePro bool wantDir string wantChannel int @@ -240,9 +251,9 @@ func Test_translatePWMPin(t *testing.T) { // act dir, channel, err := a.translatePWMPin(name) // assert - gobottest.Assert(t, err, tc.wantErr) - gobottest.Assert(t, dir, tc.wantDir) - gobottest.Assert(t, channel, tc.wantChannel) + assert.Equal(t, tc.wantErr, err) + assert.Equal(t, tc.wantDir, dir) + assert.Equal(t, tc.wantChannel, channel) }) } } diff --git a/platforms/dexter/gopigo3/driver.go b/platforms/dexter/gopigo3/driver.go index bbed8c56a..f4c3f12ad 100644 --- a/platforms/dexter/gopigo3/driver.go +++ b/platforms/dexter/gopigo3/driver.go @@ -307,9 +307,9 @@ func (g *Driver) SetLED(led Led, red, green, blue uint8) error { goPiGo3Address, SET_LED, byte(led), - byte(red), - byte(green), - byte(blue), + red, + green, + blue, }) } @@ -403,7 +403,7 @@ func (g *Driver) GetMotorStatus(motor Motor) (flags uint8, power uint16, encoder return flags, power, encoder, dps, err } // get flags - flags = uint8(response[4]) + flags = response[4] // get power power = uint16(response[5]) if power&0x80 == 0x80 { @@ -420,7 +420,7 @@ func (g *Driver) GetMotorStatus(motor Motor) (flags uint8, power uint16, encoder if e&0x80000000 == 0x80000000 { encoder = int(uint64(e) - 0x100000000) } - //get dps + // get dps d := make([]byte, 4) d[1] = response[10] d[0] = response[11] @@ -596,7 +596,7 @@ func (g *Driver) DigitalWrite(pin string, val byte) error { goPiGo3Address, SET_GROVE_STATE, byte(grovePin), - byte(val), + val, }) } diff --git a/platforms/dexter/gopigo3/driver_test.go b/platforms/dexter/gopigo3/driver_test.go index 466376ae4..ceb6982a8 100644 --- a/platforms/dexter/gopigo3/driver_test.go +++ b/platforms/dexter/gopigo3/driver_test.go @@ -4,13 +4,15 @@ import ( "encoding/hex" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" "gobot.io/x/gobot/v2/drivers/spi" - "gobot.io/x/gobot/v2/gobottest" ) -var _ gobot.Driver = (*Driver)(nil) -var negativeEncoder = false +var ( + _ gobot.Driver = (*Driver)(nil) + negativeEncoder = false +) func initTestDriver() *Driver { d := NewDriver(&TestConnector{}) @@ -20,12 +22,12 @@ func initTestDriver() *Driver { func TestDriverStart(t *testing.T) { d := initTestDriver() - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestDriverHalt(t *testing.T) { d := initTestDriver() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestDriverManufacturerName(t *testing.T) { @@ -272,8 +274,7 @@ func (ctr *TestConnector) SpiDefaultMaxSpeed() int64 { return 0 } -type TestSpiDevice struct { -} +type TestSpiDevice struct{} func (c TestSpiDevice) Close() error { return nil diff --git a/platforms/digispark/digispark_adaptor.go b/platforms/digispark/digispark_adaptor.go index d72e88173..29c0815b0 100644 --- a/platforms/digispark/digispark_adaptor.go +++ b/platforms/digispark/digispark_adaptor.go @@ -54,7 +54,6 @@ func (d *Adaptor) Finalize() (err error) { return } // DigitalWrite writes a value to the pin. Acceptable values are 1 or 0. func (d *Adaptor) DigitalWrite(pin string, level byte) (err error) { p, err := strconv.Atoi(pin) - if err != nil { return } diff --git a/platforms/digispark/digispark_adaptor_test.go b/platforms/digispark/digispark_adaptor_test.go index a4bea2319..59c6105a1 100644 --- a/platforms/digispark/digispark_adaptor_test.go +++ b/platforms/digispark/digispark_adaptor_test.go @@ -5,16 +5,18 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" "gobot.io/x/gobot/v2/drivers/gpio" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Adaptor = (*Adaptor)(nil) -var _ gpio.DigitalWriter = (*Adaptor)(nil) -var _ gpio.PwmWriter = (*Adaptor)(nil) -var _ gpio.ServoWriter = (*Adaptor)(nil) +var ( + _ gpio.DigitalWriter = (*Adaptor)(nil) + _ gpio.PwmWriter = (*Adaptor)(nil) + _ gpio.ServoWriter = (*Adaptor)(nil) +) type mock struct { locationA uint8 @@ -33,6 +35,7 @@ func (l *mock) digitalWrite(pin uint8, state uint8) error { l.state = state return l.error() } + func (l *mock) pinMode(pin uint8, mode uint8) error { l.pin = pin l.mode = mode @@ -48,6 +51,7 @@ func (l *mock) pwmUpdateCompare(channelA uint8, channelB uint8) error { l.pwmChannelB = channelB return l.error() } + func (l *mock) pwmUpdatePrescaler(value uint) error { l.pwmPrescalerValue = value return l.error() @@ -81,63 +85,63 @@ func initTestAdaptor() *Adaptor { func TestDigisparkAdaptorName(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, strings.HasPrefix(a.Name(), "Digispark"), true) + assert.True(t, strings.HasPrefix(a.Name(), "Digispark")) a.SetName("NewName") - gobottest.Assert(t, a.Name(), "NewName") + assert.Equal(t, "NewName", a.Name()) } func TestDigisparkAdaptorConnect(t *testing.T) { a := initTestAdaptor() - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) } func TestDigisparkAdaptorFinalize(t *testing.T) { a := initTestAdaptor() - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) } func TestDigisparkAdaptorDigitalWrite(t *testing.T) { a := initTestAdaptor() err := a.DigitalWrite("0", uint8(1)) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, a.littleWire.(*mock).pin, uint8(0)) - gobottest.Assert(t, a.littleWire.(*mock).state, uint8(1)) + assert.NoError(t, err) + assert.Equal(t, uint8(0), a.littleWire.(*mock).pin) + assert.Equal(t, uint8(1), a.littleWire.(*mock).state) err = a.DigitalWrite("?", uint8(1)) - gobottest.Refute(t, err, nil) + assert.NotNil(t, err) errorFunc = func() error { return errors.New("pin mode error") } err = a.DigitalWrite("0", uint8(1)) - gobottest.Assert(t, err, errors.New("pin mode error")) + assert.ErrorContains(t, err, "pin mode error") } func TestDigisparkAdaptorServoWrite(t *testing.T) { a := initTestAdaptor() err := a.ServoWrite("2", uint8(80)) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, a.littleWire.(*mock).locationA, uint8(80)) - gobottest.Assert(t, a.littleWire.(*mock).locationB, uint8(80)) + assert.NoError(t, err) + assert.Equal(t, uint8(80), a.littleWire.(*mock).locationA) + assert.Equal(t, uint8(80), a.littleWire.(*mock).locationB) a = initTestAdaptor() errorFunc = func() error { return errors.New("servo error") } err = a.ServoWrite("2", uint8(80)) - gobottest.Assert(t, err, errors.New("servo error")) + assert.ErrorContains(t, err, "servo error") } func TestDigisparkAdaptorPwmWrite(t *testing.T) { a := initTestAdaptor() err := a.PwmWrite("1", uint8(100)) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, a.littleWire.(*mock).pwmChannelA, uint8(100)) - gobottest.Assert(t, a.littleWire.(*mock).pwmChannelB, uint8(100)) + assert.NoError(t, err) + assert.Equal(t, uint8(100), a.littleWire.(*mock).pwmChannelA) + assert.Equal(t, uint8(100), a.littleWire.(*mock).pwmChannelB) a = initTestAdaptor() pwmInitErrorFunc = func() error { return errors.New("pwminit error") } err = a.PwmWrite("1", uint8(100)) - gobottest.Assert(t, err, errors.New("pwminit error")) + assert.ErrorContains(t, err, "pwminit error") a = initTestAdaptor() errorFunc = func() error { return errors.New("pwm error") } err = a.PwmWrite("1", uint8(100)) - gobottest.Assert(t, err, errors.New("pwm error")) + assert.ErrorContains(t, err, "pwm error") } diff --git a/platforms/digispark/digispark_i2c.go b/platforms/digispark/digispark_i2c.go index 07a8a9547..6249c2a20 100644 --- a/platforms/digispark/digispark_i2c.go +++ b/platforms/digispark/digispark_i2c.go @@ -38,7 +38,7 @@ func (c *digisparkI2cConnection) Test(address uint8) error { return c.adaptor.littleWire.i2cStart(address, 0) } -// UpdateDelay updates i2c signal delay amount; tune if neccessary to fit your requirements +// UpdateDelay updates i2c signal delay amount; tune if necessary to fit your requirements func (c *digisparkI2cConnection) UpdateDelay(duration uint) error { if !c.adaptor.i2c { return errors.New("Digispark i2c not initialized") diff --git a/platforms/digispark/digispark_i2c_test.go b/platforms/digispark/digispark_i2c_test.go index d2e1f12cb..5019cc160 100644 --- a/platforms/digispark/digispark_i2c_test.go +++ b/platforms/digispark/digispark_i2c_test.go @@ -1,19 +1,22 @@ package digispark import ( - "errors" "fmt" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2/drivers/i2c" - "gobot.io/x/gobot/v2/gobottest" ) -const availableI2cAddress = 0x40 -const maxUint8 = ^uint8(0) +const ( + availableI2cAddress = 0x40 + maxUint8 = ^uint8(0) +) -var _ i2c.Connector = (*Adaptor)(nil) -var i2cData = []byte{5, 4, 3, 2, 1, 0} +var ( + _ i2c.Connector = (*Adaptor)(nil) + i2cData = []byte{5, 4, 3, 2, 1, 0} +) type i2cMock struct { duration uint @@ -42,8 +45,8 @@ func TestDigisparkAdaptorI2cGetI2cConnection(t *testing.T) { c, err = a.GetI2cConnection(availableI2cAddress, a.DefaultI2cBus()) // assert - gobottest.Assert(t, err, nil) - gobottest.Refute(t, c, nil) + assert.NoError(t, err) + assert.NotNil(t, c) } func TestDigisparkAdaptorI2cGetI2cConnectionFailWithInvalidBus(t *testing.T) { @@ -54,8 +57,8 @@ func TestDigisparkAdaptorI2cGetI2cConnectionFailWithInvalidBus(t *testing.T) { c, err := a.GetI2cConnection(0x40, 1) // assert - gobottest.Assert(t, err, errors.New("Invalid bus number 1, only 0 is supported")) - gobottest.Assert(t, c, nil) + assert.ErrorContains(t, err, "Invalid bus number 1, only 0 is supported") + assert.Nil(t, c) } func TestDigisparkAdaptorI2cStartFailWithWrongAddress(t *testing.T) { @@ -68,9 +71,9 @@ func TestDigisparkAdaptorI2cStartFailWithWrongAddress(t *testing.T) { count, err := c.Write(data) // assert - gobottest.Assert(t, count, 0) - gobottest.Assert(t, err, fmt.Errorf("Invalid address, only %d is supported", availableI2cAddress)) - gobottest.Assert(t, a.littleWire.(*i2cMock).direction, maxUint8) + assert.Equal(t, 0, count) + assert.ErrorContains(t, err, fmt.Sprintf("Invalid address, only %d is supported", availableI2cAddress)) + assert.Equal(t, maxUint8, a.littleWire.(*i2cMock).direction) } func TestDigisparkAdaptorI2cWrite(t *testing.T) { @@ -84,14 +87,14 @@ func TestDigisparkAdaptorI2cWrite(t *testing.T) { count, err := c.Write(data) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, a.littleWire.(*i2cMock).writeStartWasSend, true) - gobottest.Assert(t, a.littleWire.(*i2cMock).readStartWasSend, false) - gobottest.Assert(t, a.littleWire.(*i2cMock).direction, uint8(0)) - gobottest.Assert(t, count, dataLen) - gobottest.Assert(t, a.littleWire.(*i2cMock).dataWritten, data) - gobottest.Assert(t, a.littleWire.(*i2cMock).writeStopWasSend, true) - gobottest.Assert(t, a.littleWire.(*i2cMock).readStopWasSend, false) + assert.NoError(t, err) + assert.True(t, a.littleWire.(*i2cMock).writeStartWasSend) + assert.False(t, a.littleWire.(*i2cMock).readStartWasSend) + assert.Equal(t, uint8(0), a.littleWire.(*i2cMock).direction) + assert.Equal(t, dataLen, count) + assert.Equal(t, data, a.littleWire.(*i2cMock).dataWritten) + assert.True(t, a.littleWire.(*i2cMock).writeStopWasSend) + assert.False(t, a.littleWire.(*i2cMock).readStopWasSend) } func TestDigisparkAdaptorI2cWriteByte(t *testing.T) { @@ -104,13 +107,13 @@ func TestDigisparkAdaptorI2cWriteByte(t *testing.T) { err := c.WriteByte(data) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, a.littleWire.(*i2cMock).writeStartWasSend, true) - gobottest.Assert(t, a.littleWire.(*i2cMock).readStartWasSend, false) - gobottest.Assert(t, a.littleWire.(*i2cMock).direction, uint8(0)) - gobottest.Assert(t, a.littleWire.(*i2cMock).dataWritten, []byte{data}) - gobottest.Assert(t, a.littleWire.(*i2cMock).writeStopWasSend, true) - gobottest.Assert(t, a.littleWire.(*i2cMock).readStopWasSend, false) + assert.NoError(t, err) + assert.True(t, a.littleWire.(*i2cMock).writeStartWasSend) + assert.False(t, a.littleWire.(*i2cMock).readStartWasSend) + assert.Equal(t, uint8(0), a.littleWire.(*i2cMock).direction) + assert.Equal(t, []byte{data}, a.littleWire.(*i2cMock).dataWritten) + assert.True(t, a.littleWire.(*i2cMock).writeStopWasSend) + assert.False(t, a.littleWire.(*i2cMock).readStopWasSend) } func TestDigisparkAdaptorI2cWriteByteData(t *testing.T) { @@ -124,13 +127,13 @@ func TestDigisparkAdaptorI2cWriteByteData(t *testing.T) { err := c.WriteByteData(reg, data) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, a.littleWire.(*i2cMock).writeStartWasSend, true) - gobottest.Assert(t, a.littleWire.(*i2cMock).readStartWasSend, false) - gobottest.Assert(t, a.littleWire.(*i2cMock).direction, uint8(0)) - gobottest.Assert(t, a.littleWire.(*i2cMock).dataWritten, []byte{reg, data}) - gobottest.Assert(t, a.littleWire.(*i2cMock).writeStopWasSend, true) - gobottest.Assert(t, a.littleWire.(*i2cMock).readStopWasSend, false) + assert.NoError(t, err) + assert.True(t, a.littleWire.(*i2cMock).writeStartWasSend) + assert.False(t, a.littleWire.(*i2cMock).readStartWasSend) + assert.Equal(t, uint8(0), a.littleWire.(*i2cMock).direction) + assert.Equal(t, []byte{reg, data}, a.littleWire.(*i2cMock).dataWritten) + assert.True(t, a.littleWire.(*i2cMock).writeStopWasSend) + assert.False(t, a.littleWire.(*i2cMock).readStopWasSend) } func TestDigisparkAdaptorI2cWriteWordData(t *testing.T) { @@ -144,13 +147,13 @@ func TestDigisparkAdaptorI2cWriteWordData(t *testing.T) { err := c.WriteWordData(reg, data) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, a.littleWire.(*i2cMock).writeStartWasSend, true) - gobottest.Assert(t, a.littleWire.(*i2cMock).readStartWasSend, false) - gobottest.Assert(t, a.littleWire.(*i2cMock).direction, uint8(0)) - gobottest.Assert(t, a.littleWire.(*i2cMock).dataWritten, []byte{reg, 0x08, 0x05}) - gobottest.Assert(t, a.littleWire.(*i2cMock).writeStopWasSend, true) - gobottest.Assert(t, a.littleWire.(*i2cMock).readStopWasSend, false) + assert.NoError(t, err) + assert.True(t, a.littleWire.(*i2cMock).writeStartWasSend) + assert.False(t, a.littleWire.(*i2cMock).readStartWasSend) + assert.Equal(t, uint8(0), a.littleWire.(*i2cMock).direction) + assert.Equal(t, []byte{reg, 0x08, 0x05}, a.littleWire.(*i2cMock).dataWritten) + assert.True(t, a.littleWire.(*i2cMock).writeStopWasSend) + assert.False(t, a.littleWire.(*i2cMock).readStopWasSend) } func TestDigisparkAdaptorI2cWriteBlockData(t *testing.T) { @@ -164,13 +167,13 @@ func TestDigisparkAdaptorI2cWriteBlockData(t *testing.T) { err := c.WriteBlockData(reg, data) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, a.littleWire.(*i2cMock).writeStartWasSend, true) - gobottest.Assert(t, a.littleWire.(*i2cMock).readStartWasSend, false) - gobottest.Assert(t, a.littleWire.(*i2cMock).direction, uint8(0)) - gobottest.Assert(t, a.littleWire.(*i2cMock).dataWritten, append([]byte{reg}, data...)) - gobottest.Assert(t, a.littleWire.(*i2cMock).writeStopWasSend, true) - gobottest.Assert(t, a.littleWire.(*i2cMock).readStopWasSend, false) + assert.NoError(t, err) + assert.True(t, a.littleWire.(*i2cMock).writeStartWasSend) + assert.False(t, a.littleWire.(*i2cMock).readStartWasSend) + assert.Equal(t, uint8(0), a.littleWire.(*i2cMock).direction) + assert.Equal(t, append([]byte{reg}, data...), a.littleWire.(*i2cMock).dataWritten) + assert.True(t, a.littleWire.(*i2cMock).writeStopWasSend) + assert.False(t, a.littleWire.(*i2cMock).readStopWasSend) } func TestDigisparkAdaptorI2cRead(t *testing.T) { @@ -184,14 +187,14 @@ func TestDigisparkAdaptorI2cRead(t *testing.T) { count, err := c.Read(data) // assert - gobottest.Assert(t, count, dataLen) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, a.littleWire.(*i2cMock).writeStartWasSend, false) - gobottest.Assert(t, a.littleWire.(*i2cMock).readStartWasSend, true) - gobottest.Assert(t, a.littleWire.(*i2cMock).direction, uint8(1)) - gobottest.Assert(t, data, i2cData[:dataLen]) - gobottest.Assert(t, a.littleWire.(*i2cMock).writeStopWasSend, false) - gobottest.Assert(t, a.littleWire.(*i2cMock).readStopWasSend, true) + assert.Equal(t, dataLen, count) + assert.NoError(t, err) + assert.False(t, a.littleWire.(*i2cMock).writeStartWasSend) + assert.True(t, a.littleWire.(*i2cMock).readStartWasSend) + assert.Equal(t, uint8(1), a.littleWire.(*i2cMock).direction) + assert.Equal(t, i2cData[:dataLen], data) + assert.False(t, a.littleWire.(*i2cMock).writeStopWasSend) + assert.True(t, a.littleWire.(*i2cMock).readStopWasSend) } func TestDigisparkAdaptorI2cReadByte(t *testing.T) { @@ -203,13 +206,13 @@ func TestDigisparkAdaptorI2cReadByte(t *testing.T) { data, err := c.ReadByte() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, a.littleWire.(*i2cMock).writeStartWasSend, false) - gobottest.Assert(t, a.littleWire.(*i2cMock).readStartWasSend, true) - gobottest.Assert(t, a.littleWire.(*i2cMock).direction, uint8(1)) - gobottest.Assert(t, data, i2cData[0]) - gobottest.Assert(t, a.littleWire.(*i2cMock).writeStopWasSend, false) - gobottest.Assert(t, a.littleWire.(*i2cMock).readStopWasSend, true) + assert.NoError(t, err) + assert.False(t, a.littleWire.(*i2cMock).writeStartWasSend) + assert.True(t, a.littleWire.(*i2cMock).readStartWasSend) + assert.Equal(t, uint8(1), a.littleWire.(*i2cMock).direction) + assert.Equal(t, i2cData[0], data) + assert.False(t, a.littleWire.(*i2cMock).writeStopWasSend) + assert.True(t, a.littleWire.(*i2cMock).readStopWasSend) } func TestDigisparkAdaptorI2cReadByteData(t *testing.T) { @@ -222,14 +225,14 @@ func TestDigisparkAdaptorI2cReadByteData(t *testing.T) { data, err := c.ReadByteData(reg) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, a.littleWire.(*i2cMock).writeStartWasSend, true) - gobottest.Assert(t, a.littleWire.(*i2cMock).readStartWasSend, true) - gobottest.Assert(t, a.littleWire.(*i2cMock).direction, uint8(1)) - gobottest.Assert(t, a.littleWire.(*i2cMock).dataWritten, []byte{reg}) - gobottest.Assert(t, data, i2cData[0]) - gobottest.Assert(t, a.littleWire.(*i2cMock).writeStopWasSend, false) - gobottest.Assert(t, a.littleWire.(*i2cMock).readStopWasSend, true) + assert.NoError(t, err) + assert.True(t, a.littleWire.(*i2cMock).writeStartWasSend) + assert.True(t, a.littleWire.(*i2cMock).readStartWasSend) + assert.Equal(t, uint8(1), a.littleWire.(*i2cMock).direction) + assert.Equal(t, []byte{reg}, a.littleWire.(*i2cMock).dataWritten) + assert.Equal(t, i2cData[0], data) + assert.False(t, a.littleWire.(*i2cMock).writeStopWasSend) + assert.True(t, a.littleWire.(*i2cMock).readStopWasSend) } func TestDigisparkAdaptorI2cReadWordData(t *testing.T) { @@ -244,14 +247,14 @@ func TestDigisparkAdaptorI2cReadWordData(t *testing.T) { data, err := c.ReadWordData(reg) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, a.littleWire.(*i2cMock).writeStartWasSend, true) - gobottest.Assert(t, a.littleWire.(*i2cMock).readStartWasSend, true) - gobottest.Assert(t, a.littleWire.(*i2cMock).direction, uint8(1)) - gobottest.Assert(t, a.littleWire.(*i2cMock).dataWritten, []byte{reg}) - gobottest.Assert(t, data, expectedValue) - gobottest.Assert(t, a.littleWire.(*i2cMock).writeStopWasSend, false) - gobottest.Assert(t, a.littleWire.(*i2cMock).readStopWasSend, true) + assert.NoError(t, err) + assert.True(t, a.littleWire.(*i2cMock).writeStartWasSend) + assert.True(t, a.littleWire.(*i2cMock).readStartWasSend) + assert.Equal(t, uint8(1), a.littleWire.(*i2cMock).direction) + assert.Equal(t, []byte{reg}, a.littleWire.(*i2cMock).dataWritten) + assert.Equal(t, expectedValue, data) + assert.False(t, a.littleWire.(*i2cMock).writeStopWasSend) + assert.True(t, a.littleWire.(*i2cMock).readStopWasSend) } func TestDigisparkAdaptorI2cReadBlockData(t *testing.T) { @@ -266,14 +269,14 @@ func TestDigisparkAdaptorI2cReadBlockData(t *testing.T) { err := c.ReadBlockData(reg, data) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, a.littleWire.(*i2cMock).writeStartWasSend, true) - gobottest.Assert(t, a.littleWire.(*i2cMock).readStartWasSend, true) - gobottest.Assert(t, a.littleWire.(*i2cMock).direction, uint8(1)) - gobottest.Assert(t, a.littleWire.(*i2cMock).dataWritten, []byte{reg}) - gobottest.Assert(t, data, i2cData[:dataLen]) - gobottest.Assert(t, a.littleWire.(*i2cMock).writeStopWasSend, false) - gobottest.Assert(t, a.littleWire.(*i2cMock).readStopWasSend, true) + assert.NoError(t, err) + assert.True(t, a.littleWire.(*i2cMock).writeStartWasSend) + assert.True(t, a.littleWire.(*i2cMock).readStartWasSend) + assert.Equal(t, uint8(1), a.littleWire.(*i2cMock).direction) + assert.Equal(t, []byte{reg}, a.littleWire.(*i2cMock).dataWritten) + assert.Equal(t, i2cData[:dataLen], data) + assert.False(t, a.littleWire.(*i2cMock).writeStopWasSend) + assert.True(t, a.littleWire.(*i2cMock).readStopWasSend) } func TestDigisparkAdaptorI2cUpdateDelay(t *testing.T) { @@ -285,8 +288,8 @@ func TestDigisparkAdaptorI2cUpdateDelay(t *testing.T) { err := c.(*digisparkI2cConnection).UpdateDelay(uint(100)) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, a.littleWire.(*i2cMock).duration, uint(100)) + assert.NoError(t, err) + assert.Equal(t, uint(100), a.littleWire.(*i2cMock).duration) } // setup mock for i2c tests diff --git a/platforms/digispark/littleWire.go b/platforms/digispark/littleWire.go index d3e3c3c83..0f2236835 100644 --- a/platforms/digispark/littleWire.go +++ b/platforms/digispark/littleWire.go @@ -106,7 +106,7 @@ func (l *littleWire) i2cRead(readBuffer []byte, length int, endWithStop uint8) e return l.error() } -// i2cUpdateDelay updates i2c signal delay amount. Tune if neccessary to fit your requirements +// i2cUpdateDelay updates i2c signal delay amount. Tune if necessary to fit your requirements func (l *littleWire) i2cUpdateDelay(duration uint) error { C.i2c_updateDelay(l.lwHandle, C.uint(duration)) return l.error() diff --git a/platforms/digispark/littleWire.h b/platforms/digispark/littleWire.h index a46a353b2..ada3f0dbc 100644 --- a/platforms/digispark/littleWire.h +++ b/platforms/digispark/littleWire.h @@ -405,7 +405,7 @@ void i2c_write(littleWire* lwHandle, unsigned char* sendBuffer, unsigned char le void i2c_read(littleWire* lwHandle, unsigned char* readBuffer, unsigned char length, unsigned char endWithStop); /** - * Update i2c signal delay amount. Tune if neccessary to fit your requirements. + * Update i2c signal delay amount. Tune if necessary to fit your requirements. * * @param lwHandle littleWire device pointer * @param duration Delay amount diff --git a/platforms/dji/tello/crc.go b/platforms/dji/tello/crc.go index 834a74d4a..3aa031b0d 100644 --- a/platforms/dji/tello/crc.go +++ b/platforms/dji/tello/crc.go @@ -23,7 +23,7 @@ var crc8table = []byte{ func CalculateCRC8(pkt []byte) byte { crc := byte(0x77) for _, val := range pkt { - crc = crc8table[(crc^byte(val))&0xff] + crc = crc8table[(crc^val)&0xff] } return crc diff --git a/platforms/dji/tello/driver.go b/platforms/dji/tello/driver.go index f48d28e99..808993c05 100644 --- a/platforms/dji/tello/driver.go +++ b/platforms/dji/tello/driver.go @@ -208,7 +208,8 @@ func NewDriver(port string) *Driver { // NewDriverWithIP creates a driver for the Tello EDU drone. Pass in the ip address and UDP port to use for the responses // from the drone. func NewDriverWithIP(ip string, port string) *Driver { - d := &Driver{name: gobot.DefaultName("Tello"), + d := &Driver{ + name: gobot.DefaultName("Tello"), reqAddr: ip + ":8889", respPort: port, videoPort: "11111", @@ -275,7 +276,6 @@ func (d *Driver) Start() error { panic(err) } }) - if err != nil { panic(err) } @@ -519,7 +519,7 @@ func (d *Driver) Rate() error { } // bound is a naive implementation that returns the smaller of x or y. -func bound(x, y float32) float32 { +func bound(x, y float32) float32 { //nolint:unparam // keep y as parameter if x < -y { return -y } diff --git a/platforms/dji/tello/driver_test.go b/platforms/dji/tello/driver_test.go index ecd9e22a4..3571c0160 100644 --- a/platforms/dji/tello/driver_test.go +++ b/platforms/dji/tello/driver_test.go @@ -9,8 +9,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*Driver)(nil) @@ -20,6 +20,7 @@ type WriteCloserDoNothing struct{} func (w *WriteCloserDoNothing) Write(p []byte) (n int, err error) { return 0, nil } + func (w *WriteCloserDoNothing) Close() error { return nil } @@ -27,7 +28,7 @@ func (w *WriteCloserDoNothing) Close() error { func TestNewDriver(t *testing.T) { d := NewDriver("8888") - gobottest.Assert(t, d.respPort, "8888") + assert.Equal(t, "8888", d.respPort) } func Test_handleResponse(t *testing.T) { @@ -171,7 +172,7 @@ func TestHaltShouldTerminateAllTheRelatedGoroutines(t *testing.T) { _ = d.Halt() wg.Wait() - gobottest.Assert(t, d.doneChReaderCount, int32(0)) + assert.Equal(t, int32(0), d.doneChReaderCount) } func TestHaltNotWaitForeverWhenCalledMultipleTimes(t *testing.T) { diff --git a/platforms/dji/tello/pitch_test.go b/platforms/dji/tello/pitch_test.go index 5fc1de025..840700969 100644 --- a/platforms/dji/tello/pitch_test.go +++ b/platforms/dji/tello/pitch_test.go @@ -3,17 +3,17 @@ package tello import ( "testing" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) func TestMinidroneValidatePitchWhenEqualOffset(t *testing.T) { - gobottest.Assert(t, ValidatePitch(32767.0, 32767.0), 100) + assert.Equal(t, 100, ValidatePitch(32767.0, 32767.0)) } func TestMinidroneValidatePitchWhenTiny(t *testing.T) { - gobottest.Assert(t, ValidatePitch(1.1, 32767.0), 0) + assert.Equal(t, 0, ValidatePitch(1.1, 32767.0)) } func TestMinidroneValidatePitchWhenCentered(t *testing.T) { - gobottest.Assert(t, ValidatePitch(16383.5, 32767.0), 50) + assert.Equal(t, 50, ValidatePitch(16383.5, 32767.0)) } diff --git a/platforms/dragonboard/README.md b/platforms/dragonboard/README.md index 30862006a..f7911b2a9 100644 --- a/platforms/dragonboard/README.md +++ b/platforms/dragonboard/README.md @@ -16,43 +16,9 @@ transfer the final executable to your DragonBoard and run the program on the Dra ## How to Use +Please refer to one example for your platform, e.g. [dragonboard_button.go](https://github.com/hybridgroup/gobot/blob/release/examples/dragonboard_button.go). The pin numbering used by your Gobot program should match the way your board is labeled right on the board itself. See [here](https://www.96boards.org/db410c-getting-started/HardwareDocs/HWUserManual.md/). -```go -package main - -import ( - "fmt" - - "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/drivers/gpio" - "gobot.io/x/gobot/v2/platforms/dragonboard" -) - -func main() { - dragonAdaptor := dragonboard.NewAdaptor() - button := gpio.NewButtonDriver(dragonAdaptor, "GPIO_A") - - work := func() { - gobot.On(button.Event("push"), func(data interface{}) { - fmt.Println("button pressed") - }) - - gobot.On(button.Event("release"), func(data interface{}) { - fmt.Println("button released") - }) - } - - robot := gobot.NewRobot("buttonBot", - []gobot.Connection{chipAdaptor}, - []gobot.Device{button}, - work, - ) - - robot.Start() -} -``` - ## How to Connect ### Compiling @@ -60,13 +26,13 @@ func main() { Compile your Gobot program on your workstation like this: ```sh -GOARCH=arm64 GOOS=linux go build examples/dragon_button.go +GOARCH=arm64 GOOS=linux go build examples/dragonboard_button.go ``` Once you have compiled your code, you can you can upload your program and execute it on the DragonBoard from your workstation using the `scp` and `ssh` commands like this: ```sh -scp dragon_button root@192.168.1.xx: -ssh -t root@192.168.1.xx "./dragon_button" +scp dragonboard_button root@192.168.1.xx: +ssh -t root@192.168.1.xx "./dragonboard_button" ``` diff --git a/platforms/dragonboard/dragonboard_adaptor_test.go b/platforms/dragonboard/dragonboard_adaptor_test.go index 501f3f0f2..b0b9c6e2f 100644 --- a/platforms/dragonboard/dragonboard_adaptor_test.go +++ b/platforms/dragonboard/dragonboard_adaptor_test.go @@ -1,25 +1,26 @@ package dragonboard import ( - "errors" "fmt" "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" "gobot.io/x/gobot/v2/drivers/gpio" "gobot.io/x/gobot/v2/drivers/i2c" - "gobot.io/x/gobot/v2/gobottest" ) // make sure that this Adaptor fulfills all the required interfaces -var _ gobot.Adaptor = (*Adaptor)(nil) -var _ gobot.DigitalPinnerProvider = (*Adaptor)(nil) -var _ gpio.DigitalReader = (*Adaptor)(nil) -var _ gpio.DigitalWriter = (*Adaptor)(nil) -var _ i2c.Connector = (*Adaptor)(nil) +var ( + _ gobot.Adaptor = (*Adaptor)(nil) + _ gobot.DigitalPinnerProvider = (*Adaptor)(nil) + _ gpio.DigitalReader = (*Adaptor)(nil) + _ gpio.DigitalWriter = (*Adaptor)(nil) + _ i2c.Connector = (*Adaptor)(nil) +) -func initTestAdaptor(t *testing.T) *Adaptor { +func initTestAdaptor() *Adaptor { a := NewAdaptor() if err := a.Connect(); err != nil { panic(err) @@ -28,14 +29,14 @@ func initTestAdaptor(t *testing.T) *Adaptor { } func TestName(t *testing.T) { - a := initTestAdaptor(t) - gobottest.Assert(t, strings.HasPrefix(a.Name(), "DragonBoard"), true) + a := initTestAdaptor() + assert.True(t, strings.HasPrefix(a.Name(), "DragonBoard")) a.SetName("NewName") - gobottest.Assert(t, a.Name(), "NewName") + assert.Equal(t, "NewName", a.Name()) } func TestDigitalIO(t *testing.T) { - a := initTestAdaptor(t) + a := initTestAdaptor() mockPaths := []string{ "/sys/class/gpio/export", "/sys/class/gpio/unexport", @@ -47,18 +48,18 @@ func TestDigitalIO(t *testing.T) { fs := a.sys.UseMockFilesystem(mockPaths) _ = a.DigitalWrite("GPIO_B", 1) - gobottest.Assert(t, fs.Files["/sys/class/gpio/gpio12/value"].Contents, "1") + assert.Equal(t, "1", fs.Files["/sys/class/gpio/gpio12/value"].Contents) fs.Files["/sys/class/gpio/gpio36/value"].Contents = "1" i, _ := a.DigitalRead("GPIO_A") - gobottest.Assert(t, i, 1) + assert.Equal(t, 1, i) - gobottest.Assert(t, a.DigitalWrite("GPIO_M", 1), errors.New("'GPIO_M' is not a valid id for a digital pin")) - gobottest.Assert(t, a.Finalize(), nil) + assert.ErrorContains(t, a.DigitalWrite("GPIO_M", 1), "'GPIO_M' is not a valid id for a digital pin") + assert.NoError(t, a.Finalize()) } func TestFinalizeErrorAfterGPIO(t *testing.T) { - a := initTestAdaptor(t) + a := initTestAdaptor() mockPaths := []string{ "/sys/class/gpio/export", "/sys/class/gpio/unexport", @@ -69,18 +70,18 @@ func TestFinalizeErrorAfterGPIO(t *testing.T) { } fs := a.sys.UseMockFilesystem(mockPaths) - gobottest.Assert(t, a.Connect(), nil) - gobottest.Assert(t, a.DigitalWrite("GPIO_B", 1), nil) + assert.NoError(t, a.Connect()) + assert.NoError(t, a.DigitalWrite("GPIO_B", 1)) fs.WithWriteError = true err := a.Finalize() - gobottest.Assert(t, strings.Contains(err.Error(), "write error"), true) + assert.Contains(t, err.Error(), "write error") } func TestI2cDefaultBus(t *testing.T) { - a := initTestAdaptor(t) - gobottest.Assert(t, a.DefaultI2cBus(), 0) + a := initTestAdaptor() + assert.Equal(t, 0, a.DefaultI2cBus()) } func TestI2cFinalizeWithErrors(t *testing.T) { @@ -88,20 +89,20 @@ func TestI2cFinalizeWithErrors(t *testing.T) { a := NewAdaptor() a.sys.UseMockSyscall() fs := a.sys.UseMockFilesystem([]string{"/dev/i2c-1"}) - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) con, err := a.GetI2cConnection(0xff, 1) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) _, err = con.Write([]byte{0xbf}) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) fs.WithCloseError = true // act err = a.Finalize() // assert - gobottest.Assert(t, strings.Contains(err.Error(), "close error"), true) + assert.Contains(t, err.Error(), "close error") } func Test_validateI2cBusNumber(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { busNr int wantErr error }{ @@ -127,7 +128,7 @@ func Test_validateI2cBusNumber(t *testing.T) { // act err := a.validateI2cBusNumber(tc.busNr) // assert - gobottest.Assert(t, err, tc.wantErr) + assert.Equal(t, tc.wantErr, err) }) } } diff --git a/platforms/firmata/ble_firmata_adaptor_test.go b/platforms/firmata/ble_firmata_adaptor_test.go index 6c5af4fcf..0e6c88079 100644 --- a/platforms/firmata/ble_firmata_adaptor_test.go +++ b/platforms/firmata/ble_firmata_adaptor_test.go @@ -7,8 +7,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Adaptor = (*BLEAdaptor)(nil) @@ -20,5 +20,5 @@ func initTestBLEAdaptor() *BLEAdaptor { func TestFirmataBLEAdaptor(t *testing.T) { a := initTestBLEAdaptor() - gobottest.Assert(t, strings.HasPrefix(a.Name(), "BLEFirmata"), true) + assert.True(t, strings.HasPrefix(a.Name(), "BLEFirmata")) } diff --git a/platforms/firmata/client/client.go b/platforms/firmata/client/client.go index 5b770265d..d445ed2a2 100644 --- a/platforms/firmata/client/client.go +++ b/platforms/firmata/client/client.go @@ -333,16 +333,18 @@ func (b *Client) ReportAnalog(pin int, state int) error { // I2cRead reads numBytes from address once. func (b *Client) I2cRead(address int, numBytes int) error { - return b.WriteSysex([]byte{I2CRequest, byte(address), (I2CModeRead << 3), - byte(numBytes) & 0x7F, (byte(numBytes) >> 7) & 0x7F}) + return b.WriteSysex([]byte{ + I2CRequest, byte(address), (I2CModeRead << 3), + byte(numBytes) & 0x7F, (byte(numBytes) >> 7) & 0x7F, + }) } // I2cWrite writes data to address. func (b *Client) I2cWrite(address int, data []byte) error { ret := []byte{I2CRequest, byte(address), (I2CModeWrite << 3)} for _, val := range data { - ret = append(ret, byte(val&0x7F)) - ret = append(ret, byte((val>>7)&0x7F)) + ret = append(ret, val&0x7F) + ret = append(ret, (val>>7)&0x7F) } return b.WriteSysex(ret) } @@ -360,7 +362,7 @@ func (b *Client) togglePinReporting(pin int, state int, mode byte) error { state = 0 } - return b.write([]byte{byte(mode) | byte(pin), byte(state)}) + return b.write([]byte{mode | byte(pin), byte(state)}) } // WriteSysex writes an arbitrary Sysex command to the microcontroller. @@ -421,7 +423,7 @@ func (b *Client) process() error { portValue := buf[0] | (buf[1] << 7) for i := 0; i < 8; i++ { - pinNumber := int((8*byte(port) + byte(i))) + pinNumber := int((8*port + byte(i))) if len(b.pins) > pinNumber { if b.pins[pinNumber].Mode == Input { b.pins[pinNumber].Value = int((portValue >> (byte(i) & 0x07)) & 0x01) @@ -505,9 +507,9 @@ func (b *Client) process() error { b.Publish(b.Event(fmt.Sprintf("PinState%v", pin)), b.pins[pin]) case I2CReply: reply := I2cReply{ - Address: int(byte(currentBuffer[2]) | byte(currentBuffer[3])<<7), - Register: int(byte(currentBuffer[4]) | byte(currentBuffer[5])<<7), - Data: []byte{byte(currentBuffer[6]) | byte(currentBuffer[7])<<7}, + Address: int(currentBuffer[2] | currentBuffer[3]<<7), + Register: int(currentBuffer[4] | currentBuffer[5]<<7), + Data: []byte{currentBuffer[6] | currentBuffer[7]<<7}, } for i := 8; i < len(currentBuffer); i = i + 2 { if currentBuffer[i] == byte(0xF7) { @@ -517,7 +519,7 @@ func (b *Client) process() error { break } reply.Data = append(reply.Data, - byte(currentBuffer[i])|byte(currentBuffer[i+1])<<7, + currentBuffer[i]|currentBuffer[i+1]<<7, ) } b.Publish(b.Event("I2cReply"), reply) diff --git a/platforms/firmata/client/client_test.go b/platforms/firmata/client/client_test.go index b3d557c2a..ca559ad37 100644 --- a/platforms/firmata/client/client_test.go +++ b/platforms/firmata/client/client_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) const semPublishWait = 10 * time.Millisecond @@ -16,33 +16,43 @@ type readWriteCloser struct { id string } -var testWriteData = bytes.Buffer{} -var writeDataMutex sync.Mutex +var ( + testWriteData = bytes.Buffer{} + writeDataMutex sync.Mutex +) // do not set this data directly, use always addTestReadData() -var testReadDataMap = make(map[string][]byte) -var rwDataMapMutex sync.Mutex +var ( + testReadDataMap = make(map[string][]byte) + rwDataMapMutex sync.Mutex +) // arduino uno r3 protocol response "2.3" var testDataProtocolResponse = []byte{249, 2, 3} // arduino uno r3 firmware response "StandardFirmata.ino" -var testDataFirmwareResponse = []byte{240, 121, 2, 3, 83, 0, 116, 0, 97, 0, 110, 0, 100, 0, 97, +var testDataFirmwareResponse = []byte{ + 240, 121, 2, 3, 83, 0, 116, 0, 97, 0, 110, 0, 100, 0, 97, 0, 114, 0, 100, 0, 70, 0, 105, 0, 114, 0, 109, 0, 97, 0, 116, 0, 97, 0, 46, - 0, 105, 0, 110, 0, 111, 0, 247} + 0, 105, 0, 110, 0, 111, 0, 247, +} // arduino uno r3 capabilities response -var testDataCapabilitiesResponse = []byte{240, 108, 127, 127, 0, 1, 1, 1, 4, 14, 127, 0, 1, 1, 1, 3, +var testDataCapabilitiesResponse = []byte{ + 240, 108, 127, 127, 0, 1, 1, 1, 4, 14, 127, 0, 1, 1, 1, 3, 8, 4, 14, 127, 0, 1, 1, 1, 4, 14, 127, 0, 1, 1, 1, 3, 8, 4, 14, 127, 0, 1, 1, 1, 3, 8, 4, 14, 127, 0, 1, 1, 1, 4, 14, 127, 0, 1, 1, 1, 4, 14, 127, 0, 1, 1, 1, 3, 8, 4, 14, 127, 0, 1, 1, 1, 3, 8, 4, 14, 127, 0, 1, 1, 1, 3, 8, 4, 14, 127, 0, 1, 1, 1, 4, 14, 127, 0, 1, 1, 1, 4, 14, 127, 0, 1, 1, 1, 2, 10, 127, 0, 1, 1, 1, 2, 10, 127, 0, 1, 1, 1, 2, 10, 127, 0, 1, 1, 1, 2, 10, - 127, 0, 1, 1, 1, 2, 10, 6, 1, 127, 0, 1, 1, 1, 2, 10, 6, 1, 127, 247} + 127, 0, 1, 1, 1, 2, 10, 6, 1, 127, 0, 1, 1, 1, 2, 10, 6, 1, 127, 247, +} // arduino uno r3 analog mapping response -var testDataAnalogMappingResponse = []byte{240, 106, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 0, 1, 2, 3, 4, 5, 247} +var testDataAnalogMappingResponse = []byte{ + 240, 106, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 0, 1, 2, 3, 4, 5, 247, +} func (readWriteCloser) Write(p []byte) (int, error) { writeDataMutex.Lock() @@ -79,7 +89,7 @@ func (rwc readWriteCloser) Read(b []byte) (int, error) { if len(data) < size { size = len(data) } - copy(b, []byte(data)[:size]) + copy(b, data[:size]) testReadDataMap[rwc.id] = data[size:] return size, nil } @@ -104,23 +114,23 @@ func initTestFirmataWithReadWriteCloser(name string, data ...[]byte) (*Client, r func TestPins(t *testing.T) { b, _ := initTestFirmataWithReadWriteCloser(t.Name(), testDataCapabilitiesResponse, testDataAnalogMappingResponse) - gobottest.Assert(t, len(b.Pins()), 20) - gobottest.Assert(t, len(b.analogPins), 6) + assert.Equal(t, 20, len(b.Pins())) + assert.Equal(t, 6, len(b.analogPins)) } func TestProtocolVersionQuery(t *testing.T) { b, _ := initTestFirmataWithReadWriteCloser(t.Name()) - gobottest.Assert(t, b.ProtocolVersionQuery(), nil) + assert.NoError(t, b.ProtocolVersionQuery()) } func TestFirmwareQuery(t *testing.T) { b, _ := initTestFirmataWithReadWriteCloser(t.Name()) - gobottest.Assert(t, b.FirmwareQuery(), nil) + assert.NoError(t, b.FirmwareQuery()) } func TestPinStateQuery(t *testing.T) { b, _ := initTestFirmataWithReadWriteCloser(t.Name()) - gobottest.Assert(t, b.PinStateQuery(1), nil) + assert.NoError(t, b.PinStateQuery(1)) } func TestProcessProtocolVersion(t *testing.T) { @@ -129,7 +139,7 @@ func TestProcessProtocolVersion(t *testing.T) { rwc.addTestReadData(testDataProtocolResponse) _ = b.Once(b.Event("ProtocolVersion"), func(data interface{}) { - gobottest.Assert(t, data, "2.3") + assert.Equal(t, "2.3", data) sem <- true }) @@ -148,7 +158,7 @@ func TestProcessAnalogRead0(t *testing.T) { rwc.addTestReadData([]byte{0xE0, 0x23, 0x05}) _ = b.Once(b.Event("AnalogRead0"), func(data interface{}) { - gobottest.Assert(t, data, 675) + assert.Equal(t, 675, data) sem <- true }) @@ -167,7 +177,7 @@ func TestProcessAnalogRead1(t *testing.T) { rwc.addTestReadData([]byte{0xE1, 0x23, 0x06}) _ = b.Once(b.Event("AnalogRead1"), func(data interface{}) { - gobottest.Assert(t, data, 803) + assert.Equal(t, 803, data) sem <- true }) @@ -187,7 +197,7 @@ func TestProcessDigitalRead2(t *testing.T) { rwc.addTestReadData([]byte{0x90, 0x04, 0x00}) _ = b.Once(b.Event("DigitalRead2"), func(data interface{}) { - gobottest.Assert(t, data, 1) + assert.Equal(t, 1, data) sem <- true }) @@ -207,7 +217,7 @@ func TestProcessDigitalRead4(t *testing.T) { rwc.addTestReadData([]byte{0x90, 0x16, 0x00}) _ = b.Once(b.Event("DigitalRead4"), func(data interface{}) { - gobottest.Assert(t, data, 1) + assert.Equal(t, 1, data) sem <- true }) @@ -222,23 +232,23 @@ func TestProcessDigitalRead4(t *testing.T) { func TestDigitalWrite(t *testing.T) { b, _ := initTestFirmataWithReadWriteCloser(t.Name(), testDataCapabilitiesResponse) - gobottest.Assert(t, b.DigitalWrite(13, 0), nil) + assert.NoError(t, b.DigitalWrite(13, 0)) } func TestSetPinMode(t *testing.T) { b, _ := initTestFirmataWithReadWriteCloser(t.Name(), testDataCapabilitiesResponse) - gobottest.Assert(t, b.SetPinMode(13, Output), nil) + assert.NoError(t, b.SetPinMode(13, Output)) } func TestAnalogWrite(t *testing.T) { b, _ := initTestFirmataWithReadWriteCloser(t.Name(), testDataCapabilitiesResponse) - gobottest.Assert(t, b.AnalogWrite(0, 128), nil) + assert.NoError(t, b.AnalogWrite(0, 128)) } func TestReportAnalog(t *testing.T) { b, _ := initTestFirmataWithReadWriteCloser(t.Name()) - gobottest.Assert(t, b.ReportAnalog(0, 1), nil) - gobottest.Assert(t, b.ReportAnalog(0, 0), nil) + assert.NoError(t, b.ReportAnalog(0, 1)) + assert.NoError(t, b.ReportAnalog(0, 0)) } func TestProcessPinState13(t *testing.T) { @@ -247,7 +257,7 @@ func TestProcessPinState13(t *testing.T) { rwc.addTestReadData([]byte{240, 110, 13, 1, 1, 247}) _ = b.Once(b.Event("PinState13"), func(data interface{}) { - gobottest.Assert(t, data, Pin{[]int{0, 1, 4}, 1, 0, 1, 127}) + assert.Equal(t, Pin{[]int{0, 1, 4}, 1, 0, 1, 127}, data) sem <- true }) @@ -262,22 +272,22 @@ func TestProcessPinState13(t *testing.T) { func TestI2cConfig(t *testing.T) { b, _ := initTestFirmataWithReadWriteCloser(t.Name()) - gobottest.Assert(t, b.I2cConfig(100), nil) + assert.NoError(t, b.I2cConfig(100)) } func TestI2cWrite(t *testing.T) { b, _ := initTestFirmataWithReadWriteCloser(t.Name()) - gobottest.Assert(t, b.I2cWrite(0x00, []byte{0x01, 0x02}), nil) + assert.NoError(t, b.I2cWrite(0x00, []byte{0x01, 0x02})) } func TestI2cRead(t *testing.T) { b, _ := initTestFirmataWithReadWriteCloser(t.Name()) - gobottest.Assert(t, b.I2cRead(0x00, 10), nil) + assert.NoError(t, b.I2cRead(0x00, 10)) } func TestWriteSysex(t *testing.T) { b, _ := initTestFirmataWithReadWriteCloser(t.Name()) - gobottest.Assert(t, b.WriteSysex([]byte{0x01, 0x02}), nil) + assert.NoError(t, b.WriteSysex([]byte{0x01, 0x02})) } func TestProcessI2cReply(t *testing.T) { @@ -286,11 +296,11 @@ func TestProcessI2cReply(t *testing.T) { rwc.addTestReadData([]byte{240, 119, 9, 0, 0, 0, 24, 1, 1, 0, 26, 1, 247}) _ = b.Once(b.Event("I2cReply"), func(data interface{}) { - gobottest.Assert(t, data, I2cReply{ + assert.Equal(t, I2cReply{ Address: 9, Register: 0, Data: []byte{152, 1, 154}, - }) + }, data) sem <- true }) @@ -309,7 +319,7 @@ func TestProcessFirmwareQuery(t *testing.T) { rwc.addTestReadData(testDataFirmwareResponse) _ = b.Once(b.Event("FirmwareQuery"), func(data interface{}) { - gobottest.Assert(t, data, "StandardFirmata.ino") + assert.Equal(t, "StandardFirmata.ino", data) sem <- true }) @@ -328,7 +338,7 @@ func TestProcessStringData(t *testing.T) { rwc.addTestReadData(append([]byte{240, 0x71}, append([]byte("Hello Firmata!"), 247)...)) _ = b.Once(b.Event("StringData"), func(data interface{}) { - gobottest.Assert(t, data, "Hello Firmata!") + assert.Equal(t, "Hello Firmata!", data) sem <- true }) @@ -363,9 +373,9 @@ func TestConnect(t *testing.T) { rwc.addTestReadData(testDataProtocolResponse) }) - gobottest.Assert(t, b.Connect(rwc), nil) + assert.NoError(t, b.Connect(rwc)) time.Sleep(150 * time.Millisecond) - gobottest.Assert(t, b.Disconnect(), nil) + assert.NoError(t, b.Disconnect()) } func TestServoConfig(t *testing.T) { @@ -401,8 +411,8 @@ func TestServoConfig(t *testing.T) { writeDataMutex.Unlock() err := b.ServoConfig(test.arguments[0], test.arguments[1], test.arguments[2]) writeDataMutex.Lock() - gobottest.Assert(t, testWriteData.Bytes(), test.expected) - gobottest.Assert(t, err, test.result) + assert.Equal(t, test.expected, testWriteData.Bytes()) + assert.Equal(t, test.result, err) writeDataMutex.Unlock() } } @@ -413,7 +423,7 @@ func TestProcessSysexData(t *testing.T) { rwc.addTestReadData([]byte{240, 17, 1, 2, 3, 247}) _ = b.Once("SysexResponse", func(data interface{}) { - gobottest.Assert(t, data, []byte{240, 17, 1, 2, 3, 247}) + assert.Equal(t, []byte{240, 17, 1, 2, 3, 247}, data) sem <- true }) diff --git a/platforms/firmata/firmata_adaptor.go b/platforms/firmata/firmata_adaptor.go index 5686c2bc2..ddd06751e 100644 --- a/platforms/firmata/firmata_adaptor.go +++ b/platforms/firmata/firmata_adaptor.go @@ -1,3 +1,6 @@ +//go:build !windows +// +build !windows + package firmata import ( diff --git a/platforms/firmata/firmata_adaptor_test.go b/platforms/firmata/firmata_adaptor_test.go index e02fc1a10..fa095c193 100644 --- a/platforms/firmata/firmata_adaptor_test.go +++ b/platforms/firmata/firmata_adaptor_test.go @@ -1,3 +1,6 @@ +//go:build !windows +// +build !windows + package firmata import ( @@ -8,21 +11,23 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" "gobot.io/x/gobot/v2/drivers/aio" "gobot.io/x/gobot/v2/drivers/gpio" - "gobot.io/x/gobot/v2/gobottest" "gobot.io/x/gobot/v2/platforms/firmata/client" ) // make sure that this Adaptor fulfills all required analog and digital interfaces -var _ gobot.Adaptor = (*Adaptor)(nil) -var _ gpio.DigitalReader = (*Adaptor)(nil) -var _ gpio.DigitalWriter = (*Adaptor)(nil) -var _ aio.AnalogReader = (*Adaptor)(nil) -var _ gpio.PwmWriter = (*Adaptor)(nil) -var _ gpio.ServoWriter = (*Adaptor)(nil) -var _ FirmataAdaptor = (*Adaptor)(nil) +var ( + _ gobot.Adaptor = (*Adaptor)(nil) + _ gpio.DigitalReader = (*Adaptor)(nil) + _ gpio.DigitalWriter = (*Adaptor)(nil) + _ aio.AnalogReader = (*Adaptor)(nil) + _ gpio.PwmWriter = (*Adaptor)(nil) + _ gpio.ServoWriter = (*Adaptor)(nil) + _ FirmataAdaptor = (*Adaptor)(nil) +) type readWriteCloser struct{} @@ -30,15 +35,17 @@ func (readWriteCloser) Write(p []byte) (int, error) { return testWriteData.Write(p) } -var testReadData = []byte{} -var testWriteData = bytes.Buffer{} +var ( + testReadData = []byte{} + testWriteData = bytes.Buffer{} +) func (readWriteCloser) Read(b []byte) (int, error) { size := len(b) if len(testReadData) < size { size = len(testReadData) } - copy(b, []byte(testReadData)[:size]) + copy(b, testReadData[:size]) testReadData = testReadData[size:] return size, nil @@ -69,9 +76,11 @@ func newMockFirmataBoard() *mockFirmataBoard { // setup mock for GPIO, PWM and servo tests func (mockFirmataBoard) Connect(io.ReadWriteCloser) error { return nil } + func (m mockFirmataBoard) Disconnect() error { return m.disconnectError } + func (m mockFirmataBoard) Pins() []client.Pin { return m.pins } @@ -100,113 +109,113 @@ func initTestAdaptor() *Adaptor { func TestNewAdaptor(t *testing.T) { a := NewAdaptor("/dev/null") - gobottest.Assert(t, a.Port(), "/dev/null") + assert.Equal(t, "/dev/null", a.Port()) } func TestAdaptorFinalize(t *testing.T) { a := initTestAdaptor() - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) a = initTestAdaptor() a.Board.(*mockFirmataBoard).disconnectError = errors.New("close error") - gobottest.Assert(t, a.Finalize(), errors.New("close error")) + assert.ErrorContains(t, a.Finalize(), "close error") } func TestAdaptorConnect(t *testing.T) { - var openSP = func(port string) (io.ReadWriteCloser, error) { + openSP := func(port string) (io.ReadWriteCloser, error) { return &readWriteCloser{}, nil } a := NewAdaptor("/dev/null") a.PortOpener = openSP a.Board = newMockFirmataBoard() - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) a = NewAdaptor("/dev/null") a.Board = newMockFirmataBoard() a.PortOpener = func(port string) (io.ReadWriteCloser, error) { return nil, errors.New("connect error") } - gobottest.Assert(t, a.Connect(), errors.New("connect error")) + assert.ErrorContains(t, a.Connect(), "connect error") a = NewAdaptor(&readWriteCloser{}) a.Board = newMockFirmataBoard() - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) a = NewAdaptor("/dev/null") a.Board = nil - gobottest.Assert(t, a.Disconnect(), nil) + assert.NoError(t, a.Disconnect()) } func TestAdaptorServoWrite(t *testing.T) { a := initTestAdaptor() - gobottest.Assert(t, a.ServoWrite("1", 50), nil) + assert.NoError(t, a.ServoWrite("1", 50)) } func TestAdaptorServoWriteBadPin(t *testing.T) { a := initTestAdaptor() - gobottest.Refute(t, a.ServoWrite("xyz", 50), nil) + assert.NotNil(t, a.ServoWrite("xyz", 50)) } func TestAdaptorPwmWrite(t *testing.T) { a := initTestAdaptor() - gobottest.Assert(t, a.PwmWrite("1", 50), nil) + assert.NoError(t, a.PwmWrite("1", 50)) } func TestAdaptorPwmWriteBadPin(t *testing.T) { a := initTestAdaptor() - gobottest.Refute(t, a.PwmWrite("xyz", 50), nil) + assert.NotNil(t, a.PwmWrite("xyz", 50)) } func TestAdaptorDigitalWrite(t *testing.T) { a := initTestAdaptor() - gobottest.Assert(t, a.DigitalWrite("1", 1), nil) + assert.NoError(t, a.DigitalWrite("1", 1)) } func TestAdaptorDigitalWriteBadPin(t *testing.T) { a := initTestAdaptor() - gobottest.Refute(t, a.DigitalWrite("xyz", 50), nil) + assert.NotNil(t, a.DigitalWrite("xyz", 50)) } func TestAdaptorDigitalRead(t *testing.T) { a := initTestAdaptor() val, err := a.DigitalRead("1") - gobottest.Assert(t, err, nil) - gobottest.Assert(t, val, 1) + assert.NoError(t, err) + assert.Equal(t, 1, val) val, err = a.DigitalRead("0") - gobottest.Assert(t, err, nil) - gobottest.Assert(t, val, 0) + assert.NoError(t, err) + assert.Equal(t, 0, val) } func TestAdaptorDigitalReadBadPin(t *testing.T) { a := initTestAdaptor() _, err := a.DigitalRead("xyz") - gobottest.Refute(t, err, nil) + assert.NotNil(t, err) } func TestAdaptorAnalogRead(t *testing.T) { a := initTestAdaptor() val, err := a.AnalogRead("1") - gobottest.Assert(t, val, 133) - gobottest.Assert(t, err, nil) + assert.Equal(t, 133, val) + assert.NoError(t, err) val, err = a.AnalogRead("0") - gobottest.Assert(t, err, nil) - gobottest.Assert(t, val, 0) + assert.NoError(t, err) + assert.Equal(t, 0, val) } func TestAdaptorAnalogReadBadPin(t *testing.T) { a := initTestAdaptor() _, err := a.AnalogRead("xyz") - gobottest.Refute(t, err, nil) + assert.NotNil(t, err) } func TestServoConfig(t *testing.T) { a := initTestAdaptor() err := a.ServoConfig("9", 0, 0) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) // test atoi error err = a.ServoConfig("a", 0, 0) - gobottest.Assert(t, true, strings.Contains(fmt.Sprintf("%v", err), "invalid syntax")) + assert.Equal(t, strings.Contains(fmt.Sprintf("%v", err), "invalid syntax"), true) } diff --git a/platforms/firmata/firmata_i2c.go b/platforms/firmata/firmata_i2c.go index ef7f67d02..4e7759a10 100644 --- a/platforms/firmata/firmata_i2c.go +++ b/platforms/firmata/firmata_i2c.go @@ -1,3 +1,6 @@ +//go:build !windows +// +build !windows + package firmata import ( diff --git a/platforms/firmata/firmata_i2c_test.go b/platforms/firmata/firmata_i2c_test.go index 92d5169a6..cf9142998 100644 --- a/platforms/firmata/firmata_i2c_test.go +++ b/platforms/firmata/firmata_i2c_test.go @@ -1,14 +1,16 @@ +//go:build !windows +// +build !windows + package firmata import ( - "errors" "io" "testing" "time" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" "gobot.io/x/gobot/v2/drivers/i2c" - "gobot.io/x/gobot/v2/gobottest" "gobot.io/x/gobot/v2/platforms/firmata/client" ) @@ -32,6 +34,7 @@ func (t *i2cMockFirmataBoard) I2cRead(address int, numBytes int) error { }() return nil } + func (t *i2cMockFirmataBoard) I2cWrite(address int, data []byte) error { t.i2cWritten = append(t.i2cWritten, data...) return nil @@ -72,7 +75,7 @@ func initTestTestAdaptorWithI2cConnection() (i2c.Connection, *i2cMockFirmataBoar func TestClose(t *testing.T) { i2c, _ := initTestTestAdaptorWithI2cConnection() - gobottest.Assert(t, i2c.Close(), nil) + assert.NoError(t, i2c.Close()) } func TestRead(t *testing.T) { @@ -82,11 +85,11 @@ func TestRead(t *testing.T) { buf := []byte{0} // act countRead, err := con.Read(buf) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, countRead, 1) - gobottest.Assert(t, brd.numBytesToRead, 1) - gobottest.Assert(t, buf, brd.i2cDataForRead) - gobottest.Assert(t, len(brd.i2cWritten), 0) + assert.NoError(t, err) + assert.Equal(t, 1, countRead) + assert.Equal(t, 1, brd.numBytesToRead) + assert.Equal(t, brd.i2cDataForRead, buf) + assert.Equal(t, 0, len(brd.i2cWritten)) } func TestReadByte(t *testing.T) { @@ -96,10 +99,10 @@ func TestReadByte(t *testing.T) { // act val, err := con.ReadByte() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, brd.numBytesToRead, 1) - gobottest.Assert(t, val, brd.i2cDataForRead[0]) - gobottest.Assert(t, len(brd.i2cWritten), 0) + assert.NoError(t, err) + assert.Equal(t, 1, brd.numBytesToRead) + assert.Equal(t, brd.i2cDataForRead[0], val) + assert.Equal(t, 0, len(brd.i2cWritten)) } func TestReadByteData(t *testing.T) { @@ -110,11 +113,11 @@ func TestReadByteData(t *testing.T) { // act val, err := con.ReadByteData(reg) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, brd.numBytesToRead, 1) - gobottest.Assert(t, val, brd.i2cDataForRead[0]) - gobottest.Assert(t, len(brd.i2cWritten), 1) - gobottest.Assert(t, brd.i2cWritten[0], reg) + assert.NoError(t, err) + assert.Equal(t, 1, brd.numBytesToRead) + assert.Equal(t, brd.i2cDataForRead[0], val) + assert.Equal(t, 1, len(brd.i2cWritten)) + assert.Equal(t, reg, brd.i2cWritten[0]) } func TestReadWordData(t *testing.T) { @@ -127,11 +130,11 @@ func TestReadWordData(t *testing.T) { // act val, err := con.ReadWordData(reg) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, brd.numBytesToRead, 2) - gobottest.Assert(t, val, uint16(lsb)|uint16(msb)<<8) - gobottest.Assert(t, len(brd.i2cWritten), 1) - gobottest.Assert(t, brd.i2cWritten[0], reg) + assert.NoError(t, err) + assert.Equal(t, 2, brd.numBytesToRead) + assert.Equal(t, uint16(lsb)|uint16(msb)<<8, val) + assert.Equal(t, 1, len(brd.i2cWritten)) + assert.Equal(t, reg, brd.i2cWritten[0]) } func TestReadBlockData(t *testing.T) { @@ -143,11 +146,11 @@ func TestReadBlockData(t *testing.T) { // act err := con.ReadBlockData(reg, buf) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, brd.numBytesToRead, 5) - gobottest.Assert(t, buf, brd.i2cDataForRead) - gobottest.Assert(t, len(brd.i2cWritten), 1) - gobottest.Assert(t, brd.i2cWritten[0], reg) + assert.NoError(t, err) + assert.Equal(t, 5, brd.numBytesToRead) + assert.Equal(t, brd.i2cDataForRead, buf) + assert.Equal(t, 1, len(brd.i2cWritten)) + assert.Equal(t, reg, brd.i2cWritten[0]) } func TestWrite(t *testing.T) { @@ -158,9 +161,9 @@ func TestWrite(t *testing.T) { // act written, err := con.Write(want) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, written, wantLen) - gobottest.Assert(t, brd.i2cWritten, want) + assert.NoError(t, err) + assert.Equal(t, wantLen, written) + assert.Equal(t, want, brd.i2cWritten) } func TestWrite20bytes(t *testing.T) { @@ -171,9 +174,9 @@ func TestWrite20bytes(t *testing.T) { // act written, err := con.Write(want) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, written, wantLen) - gobottest.Assert(t, brd.i2cWritten, want) + assert.NoError(t, err) + assert.Equal(t, wantLen, written) + assert.Equal(t, want, brd.i2cWritten) } func TestWriteByte(t *testing.T) { @@ -183,9 +186,9 @@ func TestWriteByte(t *testing.T) { // act err := con.WriteByte(want) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(brd.i2cWritten), 1) - gobottest.Assert(t, brd.i2cWritten[0], want) + assert.NoError(t, err) + assert.Equal(t, 1, len(brd.i2cWritten)) + assert.Equal(t, want, brd.i2cWritten[0]) } func TestWriteByteData(t *testing.T) { @@ -196,10 +199,10 @@ func TestWriteByteData(t *testing.T) { // act err := con.WriteByteData(reg, val) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(brd.i2cWritten), 2) - gobottest.Assert(t, brd.i2cWritten[0], reg) - gobottest.Assert(t, brd.i2cWritten[1], val) + assert.NoError(t, err) + assert.Equal(t, 2, len(brd.i2cWritten)) + assert.Equal(t, reg, brd.i2cWritten[0]) + assert.Equal(t, val, brd.i2cWritten[1]) } func TestWriteWordData(t *testing.T) { @@ -210,11 +213,11 @@ func TestWriteWordData(t *testing.T) { // act err := con.WriteWordData(reg, val) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(brd.i2cWritten), 3) - gobottest.Assert(t, brd.i2cWritten[0], reg) - gobottest.Assert(t, brd.i2cWritten[1], uint8(val&0x00FF)) - gobottest.Assert(t, brd.i2cWritten[2], uint8(val>>8)) + assert.NoError(t, err) + assert.Equal(t, 3, len(brd.i2cWritten)) + assert.Equal(t, reg, brd.i2cWritten[0]) + assert.Equal(t, uint8(val&0x00FF), brd.i2cWritten[1]) + assert.Equal(t, uint8(val>>8), brd.i2cWritten[2]) } func TestWriteBlockData(t *testing.T) { @@ -229,19 +232,19 @@ func TestWriteBlockData(t *testing.T) { // act err := con.WriteBlockData(reg, val) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(brd.i2cWritten), 33) - gobottest.Assert(t, brd.i2cWritten[0], reg) - gobottest.Assert(t, brd.i2cWritten[1:], val[0:32]) + assert.NoError(t, err) + assert.Equal(t, 33, len(brd.i2cWritten)) + assert.Equal(t, reg, brd.i2cWritten[0]) + assert.Equal(t, val[0:32], brd.i2cWritten[1:]) } func TestDefaultBus(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, a.DefaultI2cBus(), 0) + assert.Equal(t, 0, a.DefaultI2cBus()) } func TestGetI2cConnectionInvalidBus(t *testing.T) { a := NewAdaptor() _, err := a.GetI2cConnection(0x01, 99) - gobottest.Assert(t, err, errors.New("Invalid bus number 99, only 0 is supported")) + assert.ErrorContains(t, err, "Invalid bus number 99, only 0 is supported") } diff --git a/platforms/firmata/tcp_firmata_adaptor.go b/platforms/firmata/tcp_firmata_adaptor.go index c389a6943..af34cac96 100644 --- a/platforms/firmata/tcp_firmata_adaptor.go +++ b/platforms/firmata/tcp_firmata_adaptor.go @@ -1,3 +1,6 @@ +//go:build !windows +// +build !windows + package firmata import ( diff --git a/platforms/firmata/tcp_firmata_adaptor_test.go b/platforms/firmata/tcp_firmata_adaptor_test.go index 74b26b8df..b63937a21 100644 --- a/platforms/firmata/tcp_firmata_adaptor_test.go +++ b/platforms/firmata/tcp_firmata_adaptor_test.go @@ -1,11 +1,14 @@ +//go:build !windows +// +build !windows + package firmata import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Adaptor = (*TCPAdaptor)(nil) @@ -17,5 +20,5 @@ func initTestTCPAdaptor() *TCPAdaptor { func TestFirmataTCPAdaptor(t *testing.T) { a := initTestTCPAdaptor() - gobottest.Assert(t, strings.HasPrefix(a.Name(), "TCPFirmata"), true) + assert.True(t, strings.HasPrefix(a.Name(), "TCPFirmata")) } diff --git a/platforms/holystone/hs200/hs200_driver.go b/platforms/holystone/hs200/hs200_driver.go index c9f2808ef..e11f4114d 100644 --- a/platforms/holystone/hs200/hs200_driver.go +++ b/platforms/holystone/hs200/hs200_driver.go @@ -45,8 +45,10 @@ func NewDriver(tcpaddress string, udpaddress string) *Driver { } command[10] = checksum(command) - return &Driver{name: gobot.DefaultName("HS200"), stopc: make(chan struct{}), - tcpaddress: tcpaddress, udpaddress: udpaddress, cmd: command, mutex: &sync.RWMutex{}} + return &Driver{ + name: gobot.DefaultName("HS200"), stopc: make(chan struct{}), + tcpaddress: tcpaddress, udpaddress: udpaddress, cmd: command, mutex: &sync.RWMutex{}, + } } // Name returns the name of the device. diff --git a/platforms/holystone/hs200/hs200_driver_test.go b/platforms/holystone/hs200/hs200_driver_test.go index c63aedc87..42519a829 100644 --- a/platforms/holystone/hs200/hs200_driver_test.go +++ b/platforms/holystone/hs200/hs200_driver_test.go @@ -3,8 +3,8 @@ package hs200 import ( "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*Driver)(nil) @@ -12,6 +12,6 @@ var _ gobot.Driver = (*Driver)(nil) func TestHS200Driver(t *testing.T) { d := NewDriver("127.0.0.1:8080", "127.0.0.1:9090") - gobottest.Assert(t, d.tcpaddress, "127.0.0.1:8080") - gobottest.Assert(t, d.udpaddress, "127.0.0.1:9090") + assert.Equal(t, "127.0.0.1:8080", d.tcpaddress) + assert.Equal(t, "127.0.0.1:9090", d.udpaddress) } diff --git a/platforms/intel-iot/curie/imu_driver_test.go b/platforms/intel-iot/curie/imu_driver_test.go index 845604931..4e9a21ccd 100644 --- a/platforms/intel-iot/curie/imu_driver_test.go +++ b/platforms/intel-iot/curie/imu_driver_test.go @@ -2,13 +2,12 @@ package curie import ( "bytes" - "errors" "io" "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" "gobot.io/x/gobot/v2/platforms/firmata" "gobot.io/x/gobot/v2/platforms/firmata/client" @@ -22,15 +21,17 @@ func (readWriteCloser) Write(p []byte) (int, error) { return testWriteData.Write(p) } -var testReadData = []byte{} -var testWriteData = bytes.Buffer{} +var ( + testReadData = []byte{} + testWriteData = bytes.Buffer{} +) func (readWriteCloser) Read(b []byte) (int, error) { size := len(b) if len(testReadData) < size { size = len(testReadData) } - copy(b, []byte(testReadData)[:size]) + copy(b, testReadData[:size]) testReadData = testReadData[size:] return size, nil @@ -64,6 +65,7 @@ func (mockFirmataBoard) Connect(io.ReadWriteCloser) error { return nil } func (m mockFirmataBoard) Disconnect() error { return m.disconnectError } + func (m mockFirmataBoard) Pins() []client.Pin { return m.pins } @@ -89,144 +91,144 @@ func initTestIMUDriver() *IMUDriver { func TestIMUDriverStart(t *testing.T) { d := initTestIMUDriver() - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestIMUDriverHalt(t *testing.T) { d := initTestIMUDriver() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestIMUDriverDefaultName(t *testing.T) { d := initTestIMUDriver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "CurieIMU"), true) + assert.True(t, strings.HasPrefix(d.Name(), "CurieIMU")) } func TestIMUDriverSetName(t *testing.T) { d := initTestIMUDriver() d.SetName("mybot") - gobottest.Assert(t, d.Name(), "mybot") + assert.Equal(t, "mybot", d.Name()) } func TestIMUDriverConnection(t *testing.T) { d := initTestIMUDriver() - gobottest.Refute(t, d.Connection(), nil) + assert.NotNil(t, d.Connection()) } func TestIMUDriverReadAccelerometer(t *testing.T) { d := initTestIMUDriver() _ = d.Start() - gobottest.Assert(t, d.ReadAccelerometer(), nil) + assert.NoError(t, d.ReadAccelerometer()) } func TestIMUDriverReadAccelerometerData(t *testing.T) { _, err := parseAccelerometerData([]byte{}) - gobottest.Assert(t, err, errors.New("Invalid data")) + assert.ErrorContains(t, err, "Invalid data") result, err := parseAccelerometerData([]byte{0xF0, 0x11, 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0xf7}) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, result, &AccelerometerData{X: 1920, Y: 1920, Z: 1920}) + assert.NoError(t, err) + assert.Equal(t, &AccelerometerData{X: 1920, Y: 1920, Z: 1920}, result) } func TestIMUDriverReadGyroscope(t *testing.T) { d := initTestIMUDriver() _ = d.Start() - gobottest.Assert(t, d.ReadGyroscope(), nil) + assert.NoError(t, d.ReadGyroscope()) } func TestIMUDriverReadGyroscopeData(t *testing.T) { _, err := parseGyroscopeData([]byte{}) - gobottest.Assert(t, err, errors.New("Invalid data")) + assert.ErrorContains(t, err, "Invalid data") result, err := parseGyroscopeData([]byte{0xF0, 0x11, 0x01, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0xf7}) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, result, &GyroscopeData{X: 1920, Y: 1920, Z: 1920}) + assert.NoError(t, err) + assert.Equal(t, &GyroscopeData{X: 1920, Y: 1920, Z: 1920}, result) } func TestIMUDriverReadTemperature(t *testing.T) { d := initTestIMUDriver() _ = d.Start() - gobottest.Assert(t, d.ReadTemperature(), nil) + assert.NoError(t, d.ReadTemperature()) } func TestIMUDriverReadTemperatureData(t *testing.T) { _, err := parseTemperatureData([]byte{}) - gobottest.Assert(t, err, errors.New("Invalid data")) + assert.ErrorContains(t, err, "Invalid data") result, err := parseTemperatureData([]byte{0xF0, 0x11, 0x02, 0x00, 0x02, 0x03, 0x04, 0xf7}) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, result, float32(31.546875)) + assert.NoError(t, err) + assert.Equal(t, float32(31.546875), result) } func TestIMUDriverEnableShockDetection(t *testing.T) { d := initTestIMUDriver() _ = d.Start() - gobottest.Assert(t, d.EnableShockDetection(true), nil) + assert.NoError(t, d.EnableShockDetection(true)) } func TestIMUDriverShockDetectData(t *testing.T) { _, err := parseShockData([]byte{}) - gobottest.Assert(t, err, errors.New("Invalid data")) + assert.ErrorContains(t, err, "Invalid data") result, err := parseShockData([]byte{0xF0, 0x11, 0x03, 0x00, 0x02, 0xf7}) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, result, &ShockData{Axis: 0, Direction: 2}) + assert.NoError(t, err) + assert.Equal(t, &ShockData{Axis: 0, Direction: 2}, result) } func TestIMUDriverEnableStepCounter(t *testing.T) { d := initTestIMUDriver() _ = d.Start() - gobottest.Assert(t, d.EnableStepCounter(true), nil) + assert.NoError(t, d.EnableStepCounter(true)) } func TestIMUDriverStepCountData(t *testing.T) { _, err := parseStepData([]byte{}) - gobottest.Assert(t, err, errors.New("Invalid data")) + assert.ErrorContains(t, err, "Invalid data") result, err := parseStepData([]byte{0xF0, 0x11, 0x04, 0x00, 0x02, 0xf7}) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, result, int16(256)) + assert.NoError(t, err) + assert.Equal(t, int16(256), result) } func TestIMUDriverEnableTapDetection(t *testing.T) { d := initTestIMUDriver() _ = d.Start() - gobottest.Assert(t, d.EnableTapDetection(true), nil) + assert.NoError(t, d.EnableTapDetection(true)) } func TestIMUDriverTapDetectData(t *testing.T) { _, err := parseTapData([]byte{}) - gobottest.Assert(t, err, errors.New("Invalid data")) + assert.ErrorContains(t, err, "Invalid data") result, err := parseTapData([]byte{0xF0, 0x11, 0x05, 0x00, 0x02, 0xf7}) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, result, &TapData{Axis: 0, Direction: 2}) + assert.NoError(t, err) + assert.Equal(t, &TapData{Axis: 0, Direction: 2}, result) } func TestIMUDriverEnableReadMotion(t *testing.T) { d := initTestIMUDriver() _ = d.Start() - gobottest.Assert(t, d.ReadMotion(), nil) + assert.NoError(t, d.ReadMotion()) } func TestIMUDriverReadMotionData(t *testing.T) { _, err := parseMotionData([]byte{}) - gobottest.Assert(t, err, errors.New("Invalid data")) + assert.ErrorContains(t, err, "Invalid data") result, err := parseMotionData([]byte{0xF0, 0x11, 0x06, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0xf7}) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, result, &MotionData{AX: 1920, AY: 1920, AZ: 1920, GX: 1920, GY: 1920, GZ: 1920}) + assert.NoError(t, err) + assert.Equal(t, &MotionData{AX: 1920, AY: 1920, AZ: 1920, GX: 1920, GY: 1920, GZ: 1920}, result) } func TestIMUDriverHandleEvents(t *testing.T) { d := initTestIMUDriver() _ = d.Start() - gobottest.Assert(t, d.handleEvent([]byte{0xF0, 0x11, 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0xf7}), nil) - gobottest.Assert(t, d.handleEvent([]byte{0xF0, 0x11, 0x01, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0xf7}), nil) - gobottest.Assert(t, d.handleEvent([]byte{0xF0, 0x11, 0x02, 0x00, 0x02, 0x03, 0x04, 0xf7}), nil) - gobottest.Assert(t, d.handleEvent([]byte{0xF0, 0x11, 0x03, 0x00, 0x02, 0xf7}), nil) - gobottest.Assert(t, d.handleEvent([]byte{0xF0, 0x11, 0x04, 0x00, 0x02, 0xf7}), nil) - gobottest.Assert(t, d.handleEvent([]byte{0xF0, 0x11, 0x05, 0x00, 0x02, 0xf7}), nil) - gobottest.Assert(t, d.handleEvent([]byte{0xF0, 0x11, 0x06, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0xf7}), nil) + assert.NoError(t, d.handleEvent([]byte{0xF0, 0x11, 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0xf7})) + assert.NoError(t, d.handleEvent([]byte{0xF0, 0x11, 0x01, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0xf7})) + assert.NoError(t, d.handleEvent([]byte{0xF0, 0x11, 0x02, 0x00, 0x02, 0x03, 0x04, 0xf7})) + assert.NoError(t, d.handleEvent([]byte{0xF0, 0x11, 0x03, 0x00, 0x02, 0xf7})) + assert.NoError(t, d.handleEvent([]byte{0xF0, 0x11, 0x04, 0x00, 0x02, 0xf7})) + assert.NoError(t, d.handleEvent([]byte{0xF0, 0x11, 0x05, 0x00, 0x02, 0xf7})) + assert.NoError(t, d.handleEvent([]byte{0xF0, 0x11, 0x06, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0xf7})) } diff --git a/platforms/intel-iot/edison/edison_adaptor.go b/platforms/intel-iot/edison/edison_adaptor.go index 0dbd92bca..bcd754126 100644 --- a/platforms/intel-iot/edison/edison_adaptor.go +++ b/platforms/intel-iot/edison/edison_adaptor.go @@ -262,7 +262,7 @@ func (c *Adaptor) arduinoI2CSetup() error { } func (c *Adaptor) readFile(path string) ([]byte, error) { - file, err := c.sys.OpenFile(path, os.O_RDONLY, 0644) + file, err := c.sys.OpenFile(path, os.O_RDONLY, 0o644) defer file.Close() //nolint:staticcheck // for historical reasons if err != nil { return make([]byte, 0), err @@ -356,7 +356,7 @@ func (c *Adaptor) translateAndMuxPWMPin(id string) (string, int, error) { if err := c.digitalWrite(id, 1); err != nil { return "", -1, err } - if err := c.changePinMode(strconv.Itoa(int(sysPin.pin)), "1"); err != nil { + if err := c.changePinMode(strconv.Itoa(sysPin.pin), "1"); err != nil { return "", -1, err } return "/sys/class/pwm/pwmchip0", sysPin.pwmPin, nil @@ -378,7 +378,7 @@ func (c *Adaptor) newExportedDigitalPin(pin int, o ...func(gobot.DigitalPinOptio // changePinMode writes pin mode to current_pinmux file func (c *Adaptor) changePinMode(pin, mode string) error { - file, err := c.sys.OpenFile("/sys/kernel/debug/gpio_debug/gpio"+pin+"/current_pinmux", os.O_WRONLY, 0644) + file, err := c.sys.OpenFile("/sys/kernel/debug/gpio_debug/gpio"+pin+"/current_pinmux", os.O_WRONLY, 0o644) defer file.Close() //nolint:staticcheck // for historical reasons if err != nil { return err diff --git a/platforms/intel-iot/edison/edison_adaptor_test.go b/platforms/intel-iot/edison/edison_adaptor_test.go index 68baab0d7..e4e998b79 100644 --- a/platforms/intel-iot/edison/edison_adaptor_test.go +++ b/platforms/intel-iot/edison/edison_adaptor_test.go @@ -5,23 +5,25 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" "gobot.io/x/gobot/v2/drivers/aio" "gobot.io/x/gobot/v2/drivers/gpio" "gobot.io/x/gobot/v2/drivers/i2c" - "gobot.io/x/gobot/v2/gobottest" "gobot.io/x/gobot/v2/system" ) // make sure that this Adaptor fulfills all the required interfaces -var _ gobot.Adaptor = (*Adaptor)(nil) -var _ gobot.DigitalPinnerProvider = (*Adaptor)(nil) -var _ gobot.PWMPinnerProvider = (*Adaptor)(nil) -var _ gpio.DigitalReader = (*Adaptor)(nil) -var _ gpio.DigitalWriter = (*Adaptor)(nil) -var _ aio.AnalogReader = (*Adaptor)(nil) -var _ gpio.PwmWriter = (*Adaptor)(nil) -var _ i2c.Connector = (*Adaptor)(nil) +var ( + _ gobot.Adaptor = (*Adaptor)(nil) + _ gobot.DigitalPinnerProvider = (*Adaptor)(nil) + _ gobot.PWMPinnerProvider = (*Adaptor)(nil) + _ gpio.DigitalReader = (*Adaptor)(nil) + _ gpio.DigitalWriter = (*Adaptor)(nil) + _ aio.AnalogReader = (*Adaptor)(nil) + _ gpio.PwmWriter = (*Adaptor)(nil) + _ i2c.Connector = (*Adaptor)(nil) +) var testPinFiles = []string{ "/sys/bus/iio/devices/iio:device1/in_voltage0_raw", @@ -223,17 +225,17 @@ func initTestAdaptorWithMockedFilesystem(boardType string) (*Adaptor, *system.Mo func TestName(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, strings.HasPrefix(a.Name(), "Edison"), true) + assert.True(t, strings.HasPrefix(a.Name(), "Edison")) a.SetName("NewName") - gobottest.Assert(t, a.Name(), "NewName") + assert.Equal(t, "NewName", a.Name()) } func TestConnect(t *testing.T) { a, _ := initTestAdaptorWithMockedFilesystem("arduino") - gobottest.Assert(t, a.DefaultI2cBus(), 6) - gobottest.Assert(t, a.board, "arduino") - gobottest.Assert(t, a.Connect(), nil) + assert.Equal(t, 6, a.DefaultI2cBus()) + assert.Equal(t, "arduino", a.board) + assert.NoError(t, a.Connect()) } func TestArduinoSetupFail263(t *testing.T) { @@ -241,7 +243,7 @@ func TestArduinoSetupFail263(t *testing.T) { delete(fs.Files, "/sys/class/gpio/gpio263/direction") err := a.arduinoSetup() - gobottest.Assert(t, strings.Contains(err.Error(), "/sys/class/gpio/gpio263/direction: no such file"), true) + assert.Contains(t, err.Error(), "/sys/class/gpio/gpio263/direction: no such file") } func TestArduinoSetupFail240(t *testing.T) { @@ -249,7 +251,7 @@ func TestArduinoSetupFail240(t *testing.T) { delete(fs.Files, "/sys/class/gpio/gpio240/direction") err := a.arduinoSetup() - gobottest.Assert(t, strings.Contains(err.Error(), "/sys/class/gpio/gpio240/direction: no such file"), true) + assert.Contains(t, err.Error(), "/sys/class/gpio/gpio240/direction: no such file") } func TestArduinoSetupFail111(t *testing.T) { @@ -257,7 +259,7 @@ func TestArduinoSetupFail111(t *testing.T) { delete(fs.Files, "/sys/kernel/debug/gpio_debug/gpio111/current_pinmux") err := a.arduinoSetup() - gobottest.Assert(t, strings.Contains(err.Error(), "/sys/kernel/debug/gpio_debug/gpio111/current_pinmux: no such file"), true) + assert.Contains(t, err.Error(), "/sys/kernel/debug/gpio_debug/gpio111/current_pinmux: no such file") } func TestArduinoSetupFail131(t *testing.T) { @@ -265,56 +267,56 @@ func TestArduinoSetupFail131(t *testing.T) { delete(fs.Files, "/sys/kernel/debug/gpio_debug/gpio131/current_pinmux") err := a.arduinoSetup() - gobottest.Assert(t, strings.Contains(err.Error(), "/sys/kernel/debug/gpio_debug/gpio131/current_pinmux: no such file"), true) + assert.Contains(t, err.Error(), "/sys/kernel/debug/gpio_debug/gpio131/current_pinmux: no such file") } func TestArduinoI2CSetupFailTristate(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem("arduino") - gobottest.Assert(t, a.arduinoSetup(), nil) + assert.NoError(t, a.arduinoSetup()) fs.WithWriteError = true err := a.arduinoI2CSetup() - gobottest.Assert(t, err, fmt.Errorf("write error")) + assert.ErrorContains(t, err, "write error") } func TestArduinoI2CSetupFail14(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem("arduino") - gobottest.Assert(t, a.arduinoSetup(), nil) + assert.NoError(t, a.arduinoSetup()) delete(fs.Files, "/sys/class/gpio/gpio14/direction") err := a.arduinoI2CSetup() - gobottest.Assert(t, strings.Contains(err.Error(), "/sys/class/gpio/gpio14/direction: no such file"), true) + assert.Contains(t, err.Error(), "/sys/class/gpio/gpio14/direction: no such file") } func TestArduinoI2CSetupUnexportFail(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem("arduino") - gobottest.Assert(t, a.arduinoSetup(), nil) + assert.NoError(t, a.arduinoSetup()) delete(fs.Files, "/sys/class/gpio/unexport") err := a.arduinoI2CSetup() - gobottest.Assert(t, strings.Contains(err.Error(), "/sys/class/gpio/unexport: no such file"), true) + assert.Contains(t, err.Error(), "/sys/class/gpio/unexport: no such file") } func TestArduinoI2CSetupFail236(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem("arduino") - gobottest.Assert(t, a.arduinoSetup(), nil) + assert.NoError(t, a.arduinoSetup()) delete(fs.Files, "/sys/class/gpio/gpio236/direction") err := a.arduinoI2CSetup() - gobottest.Assert(t, strings.Contains(err.Error(), "/sys/class/gpio/gpio236/direction: no such file"), true) + assert.Contains(t, err.Error(), "/sys/class/gpio/gpio236/direction: no such file") } func TestArduinoI2CSetupFail28(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem("arduino") - gobottest.Assert(t, a.arduinoSetup(), nil) + assert.NoError(t, a.arduinoSetup()) delete(fs.Files, "/sys/kernel/debug/gpio_debug/gpio28/current_pinmux") err := a.arduinoI2CSetup() - gobottest.Assert(t, strings.Contains(err.Error(), "/sys/kernel/debug/gpio_debug/gpio28/current_pinmux: no such file"), true) + assert.Contains(t, err.Error(), "/sys/kernel/debug/gpio_debug/gpio28/current_pinmux: no such file") } func TestConnectArduinoError(t *testing.T) { @@ -322,7 +324,7 @@ func TestConnectArduinoError(t *testing.T) { fs.WithWriteError = true err := a.Connect() - gobottest.Assert(t, strings.Contains(err.Error(), "write error"), true) + assert.Contains(t, err.Error(), "write error") } func TestConnectArduinoWriteError(t *testing.T) { @@ -330,30 +332,30 @@ func TestConnectArduinoWriteError(t *testing.T) { fs.WithWriteError = true err := a.Connect() - gobottest.Assert(t, strings.Contains(err.Error(), "write error"), true) + assert.Contains(t, err.Error(), "write error") } func TestConnectSparkfun(t *testing.T) { a, _ := initTestAdaptorWithMockedFilesystem("sparkfun") - gobottest.Assert(t, a.Connect(), nil) - gobottest.Assert(t, a.DefaultI2cBus(), 1) - gobottest.Assert(t, a.board, "sparkfun") + assert.NoError(t, a.Connect()) + assert.Equal(t, 1, a.DefaultI2cBus()) + assert.Equal(t, "sparkfun", a.board) } func TestConnectMiniboard(t *testing.T) { a, _ := initTestAdaptorWithMockedFilesystem("miniboard") - gobottest.Assert(t, a.Connect(), nil) - gobottest.Assert(t, a.DefaultI2cBus(), 1) - gobottest.Assert(t, a.board, "miniboard") + assert.NoError(t, a.Connect()) + assert.Equal(t, 1, a.DefaultI2cBus()) + assert.Equal(t, "miniboard", a.board) } func TestConnectUnknown(t *testing.T) { a := NewAdaptor("wha") err := a.Connect() - gobottest.Assert(t, strings.Contains(err.Error(), "Unknown board type: wha"), true) + assert.Contains(t, err.Error(), "Unknown board type: wha") } func TestFinalize(t *testing.T) { @@ -363,18 +365,18 @@ func TestFinalize(t *testing.T) { _ = a.PwmWrite("5", 100) _, _ = a.GetI2cConnection(0xff, 6) - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) // assert that finalize after finalize is working - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) // assert that re-connect is working _ = a.Connect() // remove one file to force Finalize error delete(fs.Files, "/sys/class/gpio/unexport") err := a.Finalize() - gobottest.Assert(t, strings.Contains(err.Error(), "1 error occurred"), true) - gobottest.Assert(t, strings.Contains(err.Error(), "/sys/class/gpio/unexport"), true) + assert.Contains(t, err.Error(), "1 error occurred") + assert.Contains(t, err.Error(), "/sys/class/gpio/unexport") } func TestFinalizeError(t *testing.T) { @@ -384,22 +386,22 @@ func TestFinalizeError(t *testing.T) { fs.WithWriteError = true err := a.Finalize() - gobottest.Assert(t, strings.Contains(err.Error(), "6 errors occurred"), true) - gobottest.Assert(t, strings.Contains(err.Error(), "write error"), true) - gobottest.Assert(t, strings.Contains(err.Error(), "SetEnabled(false) failed for id 1 with write error"), true) - gobottest.Assert(t, strings.Contains(err.Error(), "Unexport() failed for id 1 with write error"), true) + assert.Contains(t, err.Error(), "6 errors occurred") + assert.Contains(t, err.Error(), "write error") + assert.Contains(t, err.Error(), "SetEnabled(false) failed for id 1 with write error") + assert.Contains(t, err.Error(), "Unexport() failed for id 1 with write error") } func TestDigitalIO(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem("arduino") _ = a.DigitalWrite("13", 1) - gobottest.Assert(t, fs.Files["/sys/class/gpio/gpio40/value"].Contents, "1") + assert.Equal(t, "1", fs.Files["/sys/class/gpio/gpio40/value"].Contents) _ = a.DigitalWrite("2", 0) i, err := a.DigitalRead("2") - gobottest.Assert(t, err, nil) - gobottest.Assert(t, i, 0) + assert.NoError(t, err) + assert.Equal(t, 0, i) } func TestDigitalPinInFileError(t *testing.T) { @@ -410,8 +412,7 @@ func TestDigitalPinInFileError(t *testing.T) { _ = a.Connect() _, err := a.DigitalPin("13") - gobottest.Assert(t, strings.Contains(err.Error(), "no such file"), true) - + assert.Contains(t, err.Error(), "no such file") } func TestDigitalPinInResistorFileError(t *testing.T) { @@ -422,7 +423,7 @@ func TestDigitalPinInResistorFileError(t *testing.T) { _ = a.Connect() _, err := a.DigitalPin("13") - gobottest.Assert(t, strings.Contains(err.Error(), "no such file"), true) + assert.Contains(t, err.Error(), "no such file") } func TestDigitalPinInLevelShifterFileError(t *testing.T) { @@ -433,7 +434,7 @@ func TestDigitalPinInLevelShifterFileError(t *testing.T) { _ = a.Connect() _, err := a.DigitalPin("13") - gobottest.Assert(t, strings.Contains(err.Error(), "no such file"), true) + assert.Contains(t, err.Error(), "no such file") } func TestDigitalPinInMuxFileError(t *testing.T) { @@ -444,7 +445,7 @@ func TestDigitalPinInMuxFileError(t *testing.T) { _ = a.Connect() _, err := a.DigitalPin("13") - gobottest.Assert(t, strings.Contains(err.Error(), "no such file"), true) + assert.Contains(t, err.Error(), "no such file") } func TestDigitalWriteError(t *testing.T) { @@ -452,7 +453,7 @@ func TestDigitalWriteError(t *testing.T) { fs.WithWriteError = true err := a.DigitalWrite("13", 1) - gobottest.Assert(t, err, fmt.Errorf("write error")) + assert.ErrorContains(t, err, "write error") } func TestDigitalReadWriteError(t *testing.T) { @@ -460,18 +461,18 @@ func TestDigitalReadWriteError(t *testing.T) { fs.WithWriteError = true _, err := a.DigitalRead("13") - gobottest.Assert(t, err, fmt.Errorf("write error")) + assert.ErrorContains(t, err, "write error") } func TestPwm(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem("arduino") err := a.PwmWrite("5", 100) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm1/duty_cycle"].Contents, "1960") + assert.NoError(t, err) + assert.Equal(t, "1960", fs.Files["/sys/class/pwm/pwmchip0/pwm1/duty_cycle"].Contents) err = a.PwmWrite("7", 100) - gobottest.Assert(t, err, fmt.Errorf("'7' is not a valid id for a PWM pin")) + assert.ErrorContains(t, err, "'7' is not a valid id for a PWM pin") } func TestPwmExportError(t *testing.T) { @@ -479,10 +480,10 @@ func TestPwmExportError(t *testing.T) { fs := a.sys.UseMockFilesystem(pwmMockPathsMux13Arduino) delete(fs.Files, "/sys/class/pwm/pwmchip0/export") err := a.Connect() - gobottest.Assert(t, err, nil) + assert.NoError(t, err) err = a.PwmWrite("5", 100) - gobottest.Assert(t, strings.Contains(err.Error(), "/sys/class/pwm/pwmchip0/export: no such file"), true) + assert.Contains(t, err.Error(), "/sys/class/pwm/pwmchip0/export: no such file") } func TestPwmEnableError(t *testing.T) { @@ -492,7 +493,7 @@ func TestPwmEnableError(t *testing.T) { _ = a.Connect() err := a.PwmWrite("5", 100) - gobottest.Assert(t, strings.Contains(err.Error(), "/sys/class/pwm/pwmchip0/pwm1/enable: no such file"), true) + assert.Contains(t, err.Error(), "/sys/class/pwm/pwmchip0/pwm1/enable: no such file") } func TestPwmWritePinError(t *testing.T) { @@ -500,7 +501,7 @@ func TestPwmWritePinError(t *testing.T) { fs.WithWriteError = true err := a.PwmWrite("5", 100) - gobottest.Assert(t, err, fmt.Errorf("write error")) + assert.ErrorContains(t, err, "write error") } func TestPwmWriteError(t *testing.T) { @@ -508,7 +509,7 @@ func TestPwmWriteError(t *testing.T) { fs.WithWriteError = true err := a.PwmWrite("5", 100) - gobottest.Assert(t, strings.Contains(err.Error(), "write error"), true) + assert.Contains(t, err.Error(), "write error") } func TestPwmReadError(t *testing.T) { @@ -516,7 +517,7 @@ func TestPwmReadError(t *testing.T) { fs.WithReadError = true err := a.PwmWrite("5", 100) - gobottest.Assert(t, strings.Contains(err.Error(), "read error"), true) + assert.Contains(t, err.Error(), "read error") } func TestAnalog(t *testing.T) { @@ -524,7 +525,7 @@ func TestAnalog(t *testing.T) { fs.Files["/sys/bus/iio/devices/iio:device1/in_voltage0_raw"].Contents = "1000\n" i, _ := a.AnalogRead("0") - gobottest.Assert(t, i, 250) + assert.Equal(t, 250, i) } func TestAnalogError(t *testing.T) { @@ -532,7 +533,7 @@ func TestAnalogError(t *testing.T) { fs.WithReadError = true _, err := a.AnalogRead("0") - gobottest.Assert(t, err, fmt.Errorf("read error")) + assert.ErrorContains(t, err, "read error") } func TestI2cWorkflow(t *testing.T) { @@ -540,17 +541,17 @@ func TestI2cWorkflow(t *testing.T) { a.sys.UseMockSyscall() con, err := a.GetI2cConnection(0xff, 6) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) _, err = con.Write([]byte{0x00, 0x01}) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) data := []byte{42, 42} _, err = con.Read(data) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, data, []byte{0x00, 0x01}) + assert.NoError(t, err) + assert.Equal(t, []byte{0x00, 0x01}, data) - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) } func TestI2cFinalizeWithErrors(t *testing.T) { @@ -558,22 +559,21 @@ func TestI2cFinalizeWithErrors(t *testing.T) { a := NewAdaptor() a.sys.UseMockSyscall() fs := a.sys.UseMockFilesystem(pwmMockPathsMux13ArduinoI2c) - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) con, err := a.GetI2cConnection(0xff, 6) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) _, err = con.Write([]byte{0x0A}) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) fs.WithCloseError = true // act err = a.Finalize() // assert - gobottest.Refute(t, err, nil) - gobottest.Assert(t, strings.Contains(err.Error(), "close error"), true) - + assert.NotNil(t, err) + assert.Contains(t, err.Error(), "close error") } func Test_validateI2cBusNumber(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { board string busNr int wantErr error @@ -613,7 +613,7 @@ func Test_validateI2cBusNumber(t *testing.T) { // act err := a.validateAndSetupI2cBusNumber(tc.busNr) // assert - gobottest.Assert(t, err, tc.wantErr) + assert.Equal(t, tc.wantErr, err) }) } } diff --git a/platforms/intel-iot/joule/joule_adaptor_test.go b/platforms/intel-iot/joule/joule_adaptor_test.go index 43771dc06..178825733 100644 --- a/platforms/intel-iot/joule/joule_adaptor_test.go +++ b/platforms/intel-iot/joule/joule_adaptor_test.go @@ -1,26 +1,27 @@ package joule import ( - "errors" "fmt" "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" "gobot.io/x/gobot/v2/drivers/gpio" "gobot.io/x/gobot/v2/drivers/i2c" - "gobot.io/x/gobot/v2/gobottest" "gobot.io/x/gobot/v2/system" ) // make sure that this Adaptor fulfills all the required interfaces -var _ gobot.Adaptor = (*Adaptor)(nil) -var _ gobot.DigitalPinnerProvider = (*Adaptor)(nil) -var _ gobot.PWMPinnerProvider = (*Adaptor)(nil) -var _ gpio.DigitalReader = (*Adaptor)(nil) -var _ gpio.DigitalWriter = (*Adaptor)(nil) -var _ gpio.PwmWriter = (*Adaptor)(nil) -var _ i2c.Connector = (*Adaptor)(nil) +var ( + _ gobot.Adaptor = (*Adaptor)(nil) + _ gobot.DigitalPinnerProvider = (*Adaptor)(nil) + _ gobot.PWMPinnerProvider = (*Adaptor)(nil) + _ gpio.DigitalReader = (*Adaptor)(nil) + _ gpio.DigitalWriter = (*Adaptor)(nil) + _ gpio.PwmWriter = (*Adaptor)(nil) + _ i2c.Connector = (*Adaptor)(nil) +) func initTestAdaptorWithMockedFilesystem() (*Adaptor, *system.MockFilesystem) { a := NewAdaptor() @@ -99,9 +100,9 @@ func initTestAdaptorWithMockedFilesystem() (*Adaptor, *system.MockFilesystem) { func TestName(t *testing.T) { a, _ := initTestAdaptorWithMockedFilesystem() - gobottest.Assert(t, strings.HasPrefix(a.Name(), "Joule"), true) + assert.True(t, strings.HasPrefix(a.Name(), "Joule")) a.SetName("NewName") - gobottest.Assert(t, a.Name(), "NewName") + assert.Equal(t, "NewName", a.Name()) } func TestFinalize(t *testing.T) { @@ -110,43 +111,43 @@ func TestFinalize(t *testing.T) { _ = a.DigitalWrite("J12_1", 1) _ = a.PwmWrite("J12_26", 100) - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) // assert finalize after finalize is working - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) // assert re-connect is working - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) } func TestDigitalIO(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem() _ = a.DigitalWrite("J12_1", 1) - gobottest.Assert(t, fs.Files["/sys/class/gpio/gpio451/value"].Contents, "1") + assert.Equal(t, "1", fs.Files["/sys/class/gpio/gpio451/value"].Contents) _ = a.DigitalWrite("J12_1", 0) i, err := a.DigitalRead("J12_1") - gobottest.Assert(t, err, nil) - gobottest.Assert(t, i, 0) + assert.NoError(t, err) + assert.Equal(t, 0, i) _, err = a.DigitalRead("P9_99") - gobottest.Assert(t, err, errors.New("'P9_99' is not a valid id for a digital pin")) + assert.ErrorContains(t, err, "'P9_99' is not a valid id for a digital pin") } func TestPwm(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem() err := a.PwmWrite("J12_26", 100) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents, "3921568") + assert.NoError(t, err) + assert.Equal(t, "3921568", fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents) err = a.PwmWrite("4", 100) - gobottest.Assert(t, err, errors.New("'4' is not a valid id for a pin")) + assert.ErrorContains(t, err, "'4' is not a valid id for a pin") err = a.PwmWrite("J12_1", 100) - gobottest.Assert(t, err, errors.New("'J12_1' is not a valid id for a PWM pin")) + assert.ErrorContains(t, err, "'J12_1' is not a valid id for a PWM pin") } func TestPwmPinExportError(t *testing.T) { @@ -154,7 +155,7 @@ func TestPwmPinExportError(t *testing.T) { delete(fs.Files, "/sys/class/pwm/pwmchip0/export") err := a.PwmWrite("J12_26", 100) - gobottest.Assert(t, strings.Contains(err.Error(), "/sys/class/pwm/pwmchip0/export: no such file"), true) + assert.Contains(t, err.Error(), "/sys/class/pwm/pwmchip0/export: no such file") } func TestPwmPinEnableError(t *testing.T) { @@ -162,12 +163,12 @@ func TestPwmPinEnableError(t *testing.T) { delete(fs.Files, "/sys/class/pwm/pwmchip0/pwm0/enable") err := a.PwmWrite("J12_26", 100) - gobottest.Assert(t, strings.Contains(err.Error(), "/sys/class/pwm/pwmchip0/pwm0/enable: no such file"), true) + assert.Contains(t, err.Error(), "/sys/class/pwm/pwmchip0/pwm0/enable: no such file") } func TestI2cDefaultBus(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, a.DefaultI2cBus(), 0) + assert.Equal(t, 0, a.DefaultI2cBus()) } func TestI2cFinalizeWithErrors(t *testing.T) { @@ -175,20 +176,20 @@ func TestI2cFinalizeWithErrors(t *testing.T) { a := NewAdaptor() a.sys.UseMockSyscall() fs := a.sys.UseMockFilesystem([]string{"/dev/i2c-2"}) - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) con, err := a.GetI2cConnection(0xff, 2) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) _, err = con.Write([]byte{0xbf}) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) fs.WithCloseError = true // act err = a.Finalize() // assert - gobottest.Assert(t, strings.Contains(err.Error(), "close error"), true) + assert.Contains(t, err.Error(), "close error") } func Test_validateI2cBusNumber(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { busNr int wantErr error }{ @@ -217,7 +218,7 @@ func Test_validateI2cBusNumber(t *testing.T) { // act err := a.validateI2cBusNumber(tc.busNr) // assert - gobottest.Assert(t, err, tc.wantErr) + assert.Equal(t, tc.wantErr, err) }) } } diff --git a/platforms/jetson/jetson_adaptor_test.go b/platforms/jetson/jetson_adaptor_test.go index cc44db01a..a3ccec3f9 100644 --- a/platforms/jetson/jetson_adaptor_test.go +++ b/platforms/jetson/jetson_adaptor_test.go @@ -1,31 +1,31 @@ package jetson import ( - "errors" "fmt" - "strings" - "testing" - "runtime" "strconv" + "strings" "sync" + "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" "gobot.io/x/gobot/v2/drivers/gpio" "gobot.io/x/gobot/v2/drivers/i2c" "gobot.io/x/gobot/v2/drivers/spi" - "gobot.io/x/gobot/v2/gobottest" "gobot.io/x/gobot/v2/system" ) // make sure that this Adaptor fulfills all the required interfaces -var _ gobot.Adaptor = (*Adaptor)(nil) -var _ gobot.DigitalPinnerProvider = (*Adaptor)(nil) -var _ gobot.PWMPinnerProvider = (*Adaptor)(nil) -var _ gpio.DigitalReader = (*Adaptor)(nil) -var _ gpio.DigitalWriter = (*Adaptor)(nil) -var _ i2c.Connector = (*Adaptor)(nil) -var _ spi.Connector = (*Adaptor)(nil) +var ( + _ gobot.Adaptor = (*Adaptor)(nil) + _ gobot.DigitalPinnerProvider = (*Adaptor)(nil) + _ gobot.PWMPinnerProvider = (*Adaptor)(nil) + _ gpio.DigitalReader = (*Adaptor)(nil) + _ gpio.DigitalWriter = (*Adaptor)(nil) + _ i2c.Connector = (*Adaptor)(nil) + _ spi.Connector = (*Adaptor)(nil) +) func initTestAdaptorWithMockedFilesystem(mockPaths []string) (*Adaptor, *system.MockFilesystem) { a := NewAdaptor() @@ -39,10 +39,10 @@ func initTestAdaptorWithMockedFilesystem(mockPaths []string) (*Adaptor, *system. func TestNewAdaptor(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, strings.HasPrefix(a.Name(), "JetsonNano"), true) + assert.True(t, strings.HasPrefix(a.Name(), "JetsonNano")) a.SetName("NewName") - gobottest.Assert(t, a.Name(), "NewName") + assert.Equal(t, "NewName", a.Name()) } func TestFinalize(t *testing.T) { @@ -59,20 +59,20 @@ func TestFinalize(t *testing.T) { _ = a.DigitalWrite("3", 1) _, _ = a.GetI2cConnection(0xff, 0) - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) } func TestPWMPinsConnect(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, a.pwmPins, (map[string]gobot.PWMPinner)(nil)) + assert.Equal(t, (map[string]gobot.PWMPinner)(nil), a.pwmPins) err := a.PwmWrite("33", 1) - gobottest.Assert(t, err.Error(), "not connected") + assert.ErrorContains(t, err, "not connected") err = a.Connect() - gobottest.Assert(t, err, nil) - gobottest.Refute(t, a.pwmPins, (map[string]gobot.PWMPinner)(nil)) - gobottest.Assert(t, len(a.pwmPins), 0) + assert.NoError(t, err) + assert.NotEqual(t, (map[string]gobot.PWMPinner)(nil), a.pwmPins) + assert.Equal(t, 0, len(a.pwmPins)) } func TestPWMPinsReConnect(t *testing.T) { @@ -85,15 +85,15 @@ func TestPWMPinsReConnect(t *testing.T) { "/sys/class/pwm/pwmchip0/pwm2/enable", } a, _ := initTestAdaptorWithMockedFilesystem(mockPaths) - gobottest.Assert(t, len(a.pwmPins), 0) - gobottest.Assert(t, a.PwmWrite("33", 1), nil) - gobottest.Assert(t, len(a.pwmPins), 1) - gobottest.Assert(t, a.Finalize(), nil) + assert.Equal(t, 0, len(a.pwmPins)) + assert.NoError(t, a.PwmWrite("33", 1)) + assert.Equal(t, 1, len(a.pwmPins)) + assert.NoError(t, a.Finalize()) // act err := a.Connect() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.pwmPins), 0) + assert.NoError(t, err) + assert.Equal(t, 0, len(a.pwmPins)) } func TestDigitalIO(t *testing.T) { @@ -108,17 +108,17 @@ func TestDigitalIO(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem(mockPaths) err := a.DigitalWrite("7", 1) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files["/sys/class/gpio/gpio216/value"].Contents, "1") + assert.NoError(t, err) + assert.Equal(t, "1", fs.Files["/sys/class/gpio/gpio216/value"].Contents) err = a.DigitalWrite("13", 1) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) i, err := a.DigitalRead("13") - gobottest.Assert(t, err, nil) - gobottest.Assert(t, i, 1) + assert.NoError(t, err) + assert.Equal(t, 1, i) - gobottest.Assert(t, a.DigitalWrite("notexist", 1), errors.New("'notexist' is not a valid id for a digital pin")) - gobottest.Assert(t, a.Finalize(), nil) + assert.ErrorContains(t, a.DigitalWrite("notexist", 1), "'notexist' is not a valid id for a digital pin") + assert.NoError(t, a.Finalize()) } func TestDigitalPinConcurrency(t *testing.T) { @@ -147,15 +147,15 @@ func TestDigitalPinConcurrency(t *testing.T) { func TestSpiDefaultValues(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, a.SpiDefaultBusNumber(), 0) - gobottest.Assert(t, a.SpiDefaultChipNumber(), 0) - gobottest.Assert(t, a.SpiDefaultMode(), 0) - gobottest.Assert(t, a.SpiDefaultMaxSpeed(), int64(10000000)) + assert.Equal(t, 0, a.SpiDefaultBusNumber()) + assert.Equal(t, 0, a.SpiDefaultChipNumber()) + assert.Equal(t, 0, a.SpiDefaultMode()) + assert.Equal(t, int64(10000000), a.SpiDefaultMaxSpeed()) } func TestI2cDefaultBus(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, a.DefaultI2cBus(), 1) + assert.Equal(t, 1, a.DefaultI2cBus()) } func TestI2cFinalizeWithErrors(t *testing.T) { @@ -163,20 +163,20 @@ func TestI2cFinalizeWithErrors(t *testing.T) { a := NewAdaptor() a.sys.UseMockSyscall() fs := a.sys.UseMockFilesystem([]string{"/dev/i2c-1"}) - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) con, err := a.GetI2cConnection(0xff, 1) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) _, err = con.Write([]byte{0xbf}) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) fs.WithCloseError = true // act err = a.Finalize() // assert - gobottest.Assert(t, strings.Contains(err.Error(), "close error"), true) + assert.Contains(t, err.Error(), "close error") } func Test_validateSpiBusNumber(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { busNr int wantErr error }{ @@ -202,13 +202,13 @@ func Test_validateSpiBusNumber(t *testing.T) { // act err := a.validateSpiBusNumber(tc.busNr) // assert - gobottest.Assert(t, err, tc.wantErr) + assert.Equal(t, tc.wantErr, err) }) } } func Test_validateI2cBusNumber(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { busNr int wantErr error }{ @@ -234,7 +234,7 @@ func Test_validateI2cBusNumber(t *testing.T) { // act err := a.validateI2cBusNumber(tc.busNr) // assert - gobottest.Assert(t, err, tc.wantErr) + assert.Equal(t, tc.wantErr, err) }) } } diff --git a/platforms/jetson/pwm_pin.go b/platforms/jetson/pwm_pin.go index 9a9fcf313..93a3f57aa 100644 --- a/platforms/jetson/pwm_pin.go +++ b/platforms/jetson/pwm_pin.go @@ -89,7 +89,7 @@ func (p *PWMPin) SetPeriod(period uint32) error { if period < minimumPeriod { return errors.New("Cannot set the period more then minimum") } - if err := p.writeFile(fmt.Sprintf("pwm%s/period", p.fn), fmt.Sprintf("%v", p.period)); err != nil { + if err := p.writeFile(fmt.Sprintf("pwm%s/period", p.fn), fmt.Sprintf("%v", period)); err != nil { return err } p.period = period @@ -126,7 +126,7 @@ func (p *PWMPin) SetDutyCycle(duty uint32) error { func (p *PWMPin) writeFile(subpath string, value string) error { sysfspath := path.Join(p.path, subpath) - fi, err := p.sys.OpenFile(sysfspath, os.O_WRONLY|os.O_APPEND, 0644) + fi, err := p.sys.OpenFile(sysfspath, os.O_WRONLY|os.O_APPEND, 0o644) defer fi.Close() //nolint:staticcheck // for historical reasons if err != nil { diff --git a/platforms/jetson/pwm_pin_test.go b/platforms/jetson/pwm_pin_test.go index a67e58e5f..a61e22753 100644 --- a/platforms/jetson/pwm_pin_test.go +++ b/platforms/jetson/pwm_pin_test.go @@ -1,11 +1,12 @@ package jetson import ( - "errors" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" "gobot.io/x/gobot/v2/system" ) @@ -13,43 +14,66 @@ var _ gobot.PWMPinner = (*PWMPin)(nil) func TestPwmPin(t *testing.T) { a := system.NewAccesser() + const ( + exportPath = "/sys/class/pwm/pwmchip0/export" + unexportPath = "/sys/class/pwm/pwmchip0/unexport" + enablePath = "/sys/class/pwm/pwmchip0/pwm3/enable" + periodPath = "/sys/class/pwm/pwmchip0/pwm3/period" + dutyCyclePath = "/sys/class/pwm/pwmchip0/pwm3/duty_cycle" + ) mockPaths := []string{ - "/sys/class/pwm/pwmchip0/export", - "/sys/class/pwm/pwmchip0/unexport", - "/sys/class/pwm/pwmchip0/pwm0/enable", - "/sys/class/pwm/pwmchip0/pwm0/period", - "/sys/class/pwm/pwmchip0/pwm0/duty_cycle", + exportPath, + unexportPath, + enablePath, + periodPath, + dutyCyclePath, } - a.UseMockFilesystem(mockPaths) + fs := a.UseMockFilesystem(mockPaths) + + pin := NewPWMPin(a, "/sys/class/pwm/pwmchip0", "3") + require.Equal(t, "", fs.Files[exportPath].Contents) + require.Equal(t, "", fs.Files[unexportPath].Contents) + require.Equal(t, "", fs.Files[enablePath].Contents) + require.Equal(t, "", fs.Files[periodPath].Contents) + require.Equal(t, "", fs.Files[dutyCyclePath].Contents) + + assert.NoError(t, pin.Export()) + assert.Equal(t, "3", fs.Files[exportPath].Contents) + + assert.NoError(t, pin.SetEnabled(true)) + assert.Equal(t, "1", fs.Files[enablePath].Contents) - pin := NewPWMPin(a, "/sys/class/pwm/pwmchip0", "0") - gobottest.Assert(t, pin.Export(), nil) - gobottest.Assert(t, pin.SetEnabled(true), nil) val, _ := pin.Polarity() - gobottest.Assert(t, val, true) - gobottest.Assert(t, pin.SetPolarity(false), nil) + assert.True(t, val) + assert.NoError(t, pin.SetPolarity(false)) val, _ = pin.Polarity() - gobottest.Assert(t, val, true) + assert.True(t, val) _, err := pin.Period() - gobottest.Assert(t, err, errors.New("Jetson PWM pin period not set")) - gobottest.Assert(t, pin.SetDutyCycle(10000), errors.New("Jetson PWM pin period not set")) + assert.ErrorContains(t, err, "Jetson PWM pin period not set") + assert.ErrorContains(t, pin.SetDutyCycle(10000), "Jetson PWM pin period not set") + assert.Equal(t, "", fs.Files[dutyCyclePath].Contents) - gobottest.Assert(t, pin.SetPeriod(20000000), nil) + assert.NoError(t, pin.SetPeriod(20000000)) + assert.Equal(t, "20000000", fs.Files[periodPath].Contents) period, _ := pin.Period() - gobottest.Assert(t, period, uint32(20000000)) - gobottest.Assert(t, pin.SetPeriod(10000000), errors.New("Cannot set the period of individual PWM pins on Jetson")) + assert.Equal(t, uint32(20000000), period) + assert.ErrorContains(t, pin.SetPeriod(10000000), "Cannot set the period of individual PWM pins on Jetson") + assert.Equal(t, "20000000", fs.Files[periodPath].Contents) dc, _ := pin.DutyCycle() - gobottest.Assert(t, dc, uint32(0)) + assert.Equal(t, uint32(0), dc) - gobottest.Assert(t, pin.SetDutyCycle(10000), nil) + assert.NoError(t, pin.SetDutyCycle(10000)) + assert.Equal(t, "10000", fs.Files[dutyCyclePath].Contents) dc, _ = pin.DutyCycle() - gobottest.Assert(t, dc, uint32(10000)) + assert.Equal(t, uint32(10000), dc) - gobottest.Assert(t, pin.SetDutyCycle(999999999), errors.New("Duty cycle exceeds period")) + assert.ErrorContains(t, pin.SetDutyCycle(999999999), "Duty cycle exceeds period") dc, _ = pin.DutyCycle() - gobottest.Assert(t, dc, uint32(10000)) + assert.Equal(t, "10000", fs.Files[dutyCyclePath].Contents) + assert.Equal(t, uint32(10000), dc) - gobottest.Assert(t, pin.Unexport(), nil) + assert.NoError(t, pin.Unexport()) + assert.Equal(t, "3", fs.Files[unexportPath].Contents) } diff --git a/platforms/joystick/LICENSE b/platforms/joystick/LICENSE index 257d22e97..f90ffa280 100644 --- a/platforms/joystick/LICENSE +++ b/platforms/joystick/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2014-2018 The Hybrid Group +Copyright (c) 2014-2023 The Hybrid Group Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/platforms/joystick/README.md b/platforms/joystick/README.md index 5e4b9d2cc..9f8f06740 100644 --- a/platforms/joystick/README.md +++ b/platforms/joystick/README.md @@ -1,6 +1,6 @@ # Joystick -You can use Gobot with any USB joystick or game controller that is compatible with [Simple DirectMedia Layer](http://www.libsdl.org/). +You can use Gobot with many USB joysticks and game controllers. Current configurations included: @@ -14,41 +14,24 @@ Current configurations included: ## How to Install -This package requires `sdl2` to be installed on your system +Any platform specific info here... ### macOS -To install `sdl2` on macOS using Homebrew: - -```sh -brew install sdl2 -``` - -To use an XBox360 controller on macOS, you will most likely need to install additional software such as [https://github.com/360Controller/360Controller](https://github.com/360Controller/360Controller). ### Linux (Ubuntu and Raspbian) -Please refer to the main [README.md](https://github.com/hybridgroup/gobot/blob/release/README.md) -You must be running a Linux kernel that is v4.14+ in order for the various controller mappings to work as expected. +### Windows -Then you must install the latest SDL2 v2.0.8 or greater: - -```sh -wget https://www.libsdl.org/release/SDL2-2.0.8.tar.gz -tar -zxvf SDL2-2.0.8.tar.gz -cd SDL2-2.0.8/ -./configure && make && sudo make install -``` ## How to Use -Controller configurations are stored in Gobot it, but you can also use external file in JSON format. Take a look at the -`configs` directory for examples. +Controller configurations are stored in Gobot, but you can also use external file in JSON format. Take a look at the `configs` directory for examples. ## How to Connect -Plug your USB joystick or game controller into your USB port. If your device is supported by SDL, you are now ready. +Plug your USB joystick or game controller into your USB port. If your device is supported by your operating system, it might prompt you to install some system drivers. For the Dualshock4, you must pair the device with your computers Bluetooth interface first, before running your Gobot program. @@ -67,7 +50,7 @@ import ( ) func main() { - joystickAdaptor := joystick.NewAdaptor() + joystickAdaptor := joystick.NewAdaptor("0") stick := joystick.NewDriver(joystickAdaptor, "dualshock3", ) @@ -151,25 +134,4 @@ func main() { ## How to Add A New Joystick -In the `bin` directory for this package is a CLI utility program that scans for SDL joystick events, and displays the ID -and value: - -```sh -$ go run ./platforms/joystick/bin/scanner.go -Joystick 0 connected -[6625 ms] Axis: 1 value:-22686 -[6641 ms] Axis: 1 value:-32768 -[6836 ms] Axis: 1 value:-18317 -[6852 ms] Axis: 1 value:0 -[8663 ms] Axis: 3 value:-32768 -[8873 ms] Axis: 3 value:0 -[10183 ms] Axis: 0 value:-24703 -[10183 ms] Axis: 0 value:-32768 -[10313 ms] Axis: 1 value:-3193 -[10329 ms] Axis: 1 value:0 -[10345 ms] Axis: 0 value:0 -``` - -You can use the output from this program to create a JSON file for the various buttons and axes on your joystick/gamepad. -You could also create a file similar to `joystick_dualshock3.go` and submit a pull request with the new configuration so -others can use it as well. +You can create a file similar to `joystick_dualshock3.go` and submit a pull request with the new configuration so others can use it as well. diff --git a/platforms/joystick/bin/scanner.go b/platforms/joystick/bin/scanner.go index 66eff923d..fb4816fcf 100644 --- a/platforms/joystick/bin/scanner.go +++ b/platforms/joystick/bin/scanner.go @@ -1,72 +1,111 @@ //go:build utils // +build utils -// // Do not build by default. // // Joystick scanner -// Based on original code from Jacky Boen -// https://github.com/veandco/go-sdl2/blob/master/examples/events/events.go - +// Based on original code from +// https://github.com/0xcafed00d/joystick/blob/master/joysticktest/joysticktest.go +// Simple program that displays the state of the specified joystick +// +// go run joysticktest.go 2 +// +// displays state of joystick id 2 package main import ( "fmt" "os" + "strconv" + "time" - "github.com/veandco/go-sdl2/sdl" + "github.com/0xcafed00d/joystick" + "github.com/nsf/termbox-go" ) -var joysticks [16]*sdl.Joystick - -func run() int { - var event sdl.Event - var running bool - - sdl.Init(sdl.INIT_JOYSTICK) - defer sdl.Quit() - - sdl.JoystickEventState(sdl.ENABLE) - - running = true - for running { - for event = sdl.PollEvent(); event != nil; event = sdl.PollEvent() { - switch t := event.(type) { - case *sdl.QuitEvent: - running = false - case *sdl.JoyAxisEvent: - fmt.Printf("[%d ms] Axis: %d\tvalue:%d\n", - t.Timestamp, t.Axis, t.Value) - case *sdl.JoyBallEvent: - fmt.Printf("[%d ms] Ball:%d\txrel:%d\tyrel:%d\n", - t.Timestamp, t.Ball, t.XRel, t.YRel) - case *sdl.JoyButtonEvent: - fmt.Printf("[%d ms] Button:%d\tstate:%d\n", - t.Timestamp, t.Button, t.State) - case *sdl.JoyHatEvent: - fmt.Printf("[%d ms] Hat:%d\tvalue:%d\n", - t.Timestamp, t.Hat, t.Value) - case *sdl.JoyDeviceAddedEvent: - joysticks[int(t.Which)] = sdl.JoystickOpen(int(t.Which)) - if joysticks[int(t.Which)] != nil { - fmt.Printf("Joystick %d connected\n", t.Which) - } - case *sdl.JoyDeviceRemovedEvent: - if joystick := joysticks[int(t.Which)]; joystick != nil { - joystick.Close() - } - fmt.Printf("Joystick %d disconnected\n", t.Which) - default: - fmt.Printf("Unknown event\n") - } +func printAt(x, y int, s string) { + for _, r := range s { + termbox.SetCell(x, y, r, termbox.ColorDefault, termbox.ColorDefault) + x++ + } +} + +func readJoystick(js joystick.Joystick) { + jinfo, err := js.Read() + if err != nil { + printAt(1, 5, "Error: "+err.Error()) + return + } + + printAt(1, 5, "Buttons:") + for button := 0; button < js.ButtonCount(); button++ { + if jinfo.Buttons&(1< 1 { + i, err := strconv.Atoi(os.Args[1]) + if err != nil { + fmt.Println(err) + return + } + jsid = i + } + + js, jserr := joystick.Open(jsid) + + if jserr != nil { + fmt.Println(jserr) + return + } + + err := termbox.Init() + if err != nil { + panic(err) + } + defer termbox.Close() + + eventQueue := make(chan termbox.Event) + go func() { + for { + eventQueue <- termbox.PollEvent() + } + }() + + ticker := time.NewTicker(time.Millisecond * 40) + + for doQuit := false; !doQuit; { + select { + case ev := <-eventQueue: + if ev.Type == termbox.EventKey { + if ev.Ch == 'q' { + doQuit = true + } + } + if ev.Type == termbox.EventResize { + termbox.Flush() + } + + case <-ticker.C: + printAt(1, 0, "-- Press 'q' to Exit --") + printAt(1, 1, fmt.Sprintf("Joystick Name: %s", js.Name())) + printAt(1, 2, fmt.Sprintf(" Axis Count: %d", js.AxisCount())) + printAt(1, 3, fmt.Sprintf(" Button Count: %d", js.ButtonCount())) + readJoystick(js) + termbox.Flush() + } + } } diff --git a/platforms/joystick/configs/dualshock3.json b/platforms/joystick/configs/dualshock3.json index f74f5b963..24195932e 100644 --- a/platforms/joystick/configs/dualshock3.json +++ b/platforms/joystick/configs/dualshock3.json @@ -11,12 +11,20 @@ "id": 1 }, { - "name": "right_x", + "name": "l2", "id": 2 }, { - "name": "right_y", + "name": "right_x", "id": 3 + }, + { + "name": "right_y", + "id": 4 + }, + { + "name": "r2", + "id": 5 } ], "buttons": [ diff --git a/platforms/joystick/doc.go b/platforms/joystick/doc.go index c0f7c8f60..3b5fcd64e 100644 --- a/platforms/joystick/doc.go +++ b/platforms/joystick/doc.go @@ -1,11 +1,9 @@ /* -Package joystick provides the Gobot adaptor and drivers for game controllers that are compatible with SDL. +Package joystick provides the Gobot adaptor and drivers for game controllers and joysticks. Installing: - This package requires `sdl2` to be installed on your system - - Please refer to the main [README.md](https://github.com/hybridgroup/gobot/blob/release/README.md) + Please refer to the main [README.md](https://github.com/hybridgroup/gobot/blob/release/README.md) Example: @@ -19,10 +17,8 @@ Example: ) func main() { - joystickAdaptor := joystick.NewAdaptor() - joystick := joystick.NewDriver(joystickAdaptor, - "./platforms/joystick/configs/dualshock3.json", - ) + joystickAdaptor := joystick.NewAdaptor("0") + joystick := joystick.NewDriver(joystickAdaptor, "dualshock3") work := func() { joystick.On(joystick.Event("square_press"), func(data interface{}) { diff --git a/platforms/joystick/joystick_adaptor.go b/platforms/joystick/joystick_adaptor.go index 2d5f93789..fba07f6bd 100644 --- a/platforms/joystick/joystick_adaptor.go +++ b/platforms/joystick/joystick_adaptor.go @@ -1,38 +1,41 @@ package joystick import ( - "errors" + "fmt" + "strconv" "gobot.io/x/gobot/v2" - "github.com/veandco/go-sdl2/sdl" + js "github.com/0xcafed00d/joystick" ) -type joystick interface { - Close() - InstanceID() sdl.JoystickID -} - // Adaptor represents a connection to a joystick type Adaptor struct { name string - joystick joystick + id string + joystick js.Joystick connect func(*Adaptor) error } // NewAdaptor returns a new Joystick Adaptor. -func NewAdaptor() *Adaptor { +// Pass in the ID of the joystick you wish to connect to. +func NewAdaptor(id string) *Adaptor { return &Adaptor{ name: gobot.DefaultName("Joystick"), connect: func(j *Adaptor) error { - if err := sdl.Init(sdl.INIT_JOYSTICK); err != nil { - return err + i, err := strconv.Atoi(id) + if err != nil { + return fmt.Errorf("Invalid joystick ID: %v", err) } - if sdl.NumJoysticks() > 0 { - j.joystick = sdl.JoystickOpen(0) - return nil + + joy, err := js.Open(i) + if err != nil { + return fmt.Errorf("No joystick available: %v", err) } - return errors.New("No joystick available") + + j.id = id + j.joystick = joy + return nil }, } } diff --git a/platforms/joystick/joystick_adaptor_test.go b/platforms/joystick/joystick_adaptor_test.go index 4f11ca06a..98ef288fd 100644 --- a/platforms/joystick/joystick_adaptor_test.go +++ b/platforms/joystick/joystick_adaptor_test.go @@ -1,18 +1,18 @@ package joystick import ( - "errors" "strings" "testing" + "github.com/stretchr/testify/assert" + "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Adaptor = (*Adaptor)(nil) func initTestAdaptor() *Adaptor { - a := NewAdaptor() + a := NewAdaptor("6") a.connect = func(j *Adaptor) (err error) { j.joystick = &testJoystick{} return nil @@ -22,21 +22,22 @@ func initTestAdaptor() *Adaptor { func TestJoystickAdaptorName(t *testing.T) { a := initTestAdaptor() - gobottest.Assert(t, strings.HasPrefix(a.Name(), "Joystick"), true) + assert.True(t, strings.HasPrefix(a.Name(), "Joystick")) a.SetName("NewName") - gobottest.Assert(t, a.Name(), "NewName") + assert.Equal(t, a.Name(), "NewName") } func TestAdaptorConnect(t *testing.T) { a := initTestAdaptor() - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) - a = NewAdaptor() - gobottest.Assert(t, a.Connect(), errors.New("No joystick available")) + a = NewAdaptor("6") + err := a.Connect() + assert.True(t, strings.HasPrefix(err.Error(), "No joystick available")) } func TestAdaptorFinalize(t *testing.T) { a := initTestAdaptor() _ = a.Connect() - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) } diff --git a/platforms/joystick/joystick_driver.go b/platforms/joystick/joystick_driver.go index 09634c234..c313f362d 100644 --- a/platforms/joystick/joystick_driver.go +++ b/platforms/joystick/joystick_driver.go @@ -6,7 +6,7 @@ import ( "os" "time" - "github.com/veandco/go-sdl2/sdl" + js "github.com/0xcafed00d/joystick" "gobot.io/x/gobot/v2" ) @@ -41,13 +41,15 @@ const ( // Driver represents a joystick type Driver struct { - name string - interval time.Duration - connection gobot.Connection - configPath string - config joystickConfig - poll func() sdl.Event - halt chan bool + name string + interval time.Duration + connection gobot.Connection + configPath string + config joystickConfig + buttonState map[int]bool + axisState map[int]int + + halt chan bool gobot.Eventer } @@ -57,20 +59,12 @@ type pair struct { ID int `json:"id"` } -// hat is a JSON representation of hat, name and id -type hat struct { - Hat int `json:"hat"` - Name string `json:"name"` - ID int `json:"id"` -} - // joystickConfig is a JSON representation of configuration values type joystickConfig struct { Name string `json:"name"` GUID string `json:"guid"` Axis []pair `json:"axis"` Buttons []pair `json:"buttons"` - Hats []hat `json:"Hats"` } // NewDriver returns a new Driver with a polling interval of @@ -82,13 +76,13 @@ type joystickConfig struct { // time.Duration: Interval at which the Driver is polled for new information func NewDriver(a *Adaptor, config string, v ...time.Duration) *Driver { d := &Driver{ - name: gobot.DefaultName("Joystick"), - connection: a, - Eventer: gobot.NewEventer(), - configPath: config, - poll: func() sdl.Event { - return sdl.PollEvent() - }, + name: gobot.DefaultName("Joystick"), + connection: a, + Eventer: gobot.NewEventer(), + configPath: config, + buttonState: make(map[int]bool), + axisState: make(map[int]int), + interval: 10 * time.Millisecond, halt: make(chan bool), } @@ -125,7 +119,43 @@ func (j *Driver) adaptor() *Adaptor { // [button]_press // [button]_release // [axis] -func (j *Driver) Start() (err error) { +func (j *Driver) Start() error { + if err := j.initConfig(); err != nil { + return err + } + + j.initEvents() + + go func() { + for { + state, err := j.adaptor().joystick.Read() + if err != nil { + j.Publish(j.Event("error"), err) + break + } + + // might just be missing a button definition, so keep going + if err := j.handleButtons(state); err != nil { + j.Publish(j.Event("error"), err) + } + + // might just be missing an axis definition, so keep going + if err := j.handleAxes(state); err != nil { + j.Publish(j.Event("error"), err) + } + + select { + case <-time.After(j.interval): + case <-j.halt: + return + } + } + }() + + return nil +} + +func (j *Driver) initConfig() error { switch j.configPath { case Dualshock3: j.config = dualshock3Config @@ -148,10 +178,14 @@ func (j *Driver) Start() (err error) { default: err := j.loadFile() if err != nil { - return err + return fmt.Errorf("loadfile error: %w", err) } } + return nil +} + +func (j *Driver) initEvents() { for _, value := range j.config.Buttons { j.AddEvent(fmt.Sprintf("%s_press", value.Name)) j.AddEvent(fmt.Sprintf("%s_release", value.Name)) @@ -159,26 +193,6 @@ func (j *Driver) Start() (err error) { for _, value := range j.config.Axis { j.AddEvent(value.Name) } - for _, value := range j.config.Hats { - j.AddEvent(fmt.Sprintf("%s_press", value.Name)) - j.AddEvent(fmt.Sprintf("%s_release", value.Name)) - } - - go func() { - for { - for event := j.poll(); event != nil; event = j.poll() { - if errs := j.handleEvent(event); errs != nil { - j.Publish(j.Event("error"), errs) - } - } - select { - case <-time.After(j.interval): - case <-j.halt: - return - } - } - }() - return } // Halt stops joystick driver @@ -187,48 +201,44 @@ func (j *Driver) Halt() (err error) { return } -var previousHat = "" - -// HandleEvent publishes an specific event according to data received -func (j *Driver) handleEvent(event sdl.Event) error { - switch data := event.(type) { - case *sdl.JoyAxisEvent: - if data.Which == j.adaptor().joystick.InstanceID() { - axis := j.findName(data.Axis, j.config.Axis) - if axis == "" { - return fmt.Errorf("Unknown Axis: %v", data.Axis) +func (j *Driver) handleButtons(state js.State) error { + for button := 0; button < j.adaptor().joystick.ButtonCount(); button++ { + buttonPressed := state.Buttons&(1<> 8) ^ (uint16(tmp) << 8) ^ (uint16(tmp) << 3) ^ (uint16(tmp) >> 4) + crcAccum = (crcAccum >> 8) ^ (uint16(tmp) << 8) ^ (uint16(tmp) << 3) ^ (uint16(tmp) >> 4) return crcAccum } diff --git a/platforms/mavlink/mavlink_adaptor_test.go b/platforms/mavlink/mavlink_adaptor_test.go index edc484a27..194bc54ee 100644 --- a/platforms/mavlink/mavlink_adaptor_test.go +++ b/platforms/mavlink/mavlink_adaptor_test.go @@ -6,8 +6,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Adaptor = (*Adaptor)(nil) @@ -54,30 +54,30 @@ func initTestMavlinkAdaptor() *Adaptor { func TestMavlinkAdaptor(t *testing.T) { a := initTestMavlinkAdaptor() - gobottest.Assert(t, a.Port(), "/dev/null") + assert.Equal(t, "/dev/null", a.Port()) } func TestMavlinkAdaptorName(t *testing.T) { a := initTestMavlinkAdaptor() - gobottest.Assert(t, strings.HasPrefix(a.Name(), "Mavlink"), true) + assert.True(t, strings.HasPrefix(a.Name(), "Mavlink")) a.SetName("NewName") - gobottest.Assert(t, a.Name(), "NewName") + assert.Equal(t, "NewName", a.Name()) } func TestMavlinkAdaptorConnect(t *testing.T) { a := initTestMavlinkAdaptor() - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) a.connect = func(port string) (io.ReadWriteCloser, error) { return nil, errors.New("connect error") } - gobottest.Assert(t, a.Connect(), errors.New("connect error")) + assert.ErrorContains(t, a.Connect(), "connect error") } func TestMavlinkAdaptorFinalize(t *testing.T) { a := initTestMavlinkAdaptor() - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) testAdaptorClose = func() error { return errors.New("close error") } - gobottest.Assert(t, a.Finalize(), errors.New("close error")) + assert.ErrorContains(t, a.Finalize(), "close error") } diff --git a/platforms/mavlink/mavlink_driver.go b/platforms/mavlink/mavlink_driver.go index 97c12cdd5..d4330633d 100644 --- a/platforms/mavlink/mavlink_driver.go +++ b/platforms/mavlink/mavlink_driver.go @@ -25,8 +25,7 @@ type Driver struct { gobot.Eventer } -type MavlinkInterface interface { -} +type MavlinkInterface interface{} // NewDriver creates a new mavlink driver. // diff --git a/platforms/mavlink/mavlink_driver_test.go b/platforms/mavlink/mavlink_driver_test.go index 4ac9c5cb4..5c6846f82 100644 --- a/platforms/mavlink/mavlink_driver_test.go +++ b/platforms/mavlink/mavlink_driver_test.go @@ -6,8 +6,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" common "gobot.io/x/gobot/v2/platforms/mavlink/common" ) @@ -26,18 +26,18 @@ func TestMavlinkDriver(t *testing.T) { m.connect = func(port string) (io.ReadWriteCloser, error) { return nil, nil } d := NewDriver(m) - gobottest.Refute(t, d.Connection(), nil) - gobottest.Assert(t, d.interval, 10*time.Millisecond) + assert.NotNil(t, d.Connection()) + assert.Equal(t, 10*time.Millisecond, d.interval) d = NewDriver(m, 100*time.Millisecond) - gobottest.Assert(t, d.interval, 100*time.Millisecond) + assert.Equal(t, 100*time.Millisecond, d.interval) } func TestMavlinkDriverName(t *testing.T) { d := initTestMavlinkDriver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "Mavlink"), true) + assert.True(t, strings.HasPrefix(d.Name(), "Mavlink")) d.SetName("NewName") - gobottest.Assert(t, d.Name(), "NewName") + assert.Equal(t, "NewName", d.Name()) } func TestMavlinkDriverStart(t *testing.T) { @@ -59,11 +59,11 @@ func TestMavlinkDriverStart(t *testing.T) { err <- data.(error) }) - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) select { case p := <-packet: - gobottest.Assert(t, d.SendPacket(p), nil) + assert.NoError(t, d.SendPacket(p)) case <-time.After(100 * time.Millisecond): t.Errorf("packet was not emitted") @@ -82,5 +82,5 @@ func TestMavlinkDriverStart(t *testing.T) { func TestMavlinkDriverHalt(t *testing.T) { d := initTestMavlinkDriver() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } diff --git a/platforms/mavlink/mavlink_udp_adaptor_test.go b/platforms/mavlink/mavlink_udp_adaptor_test.go index 5e9f1dd00..8705a3f6d 100644 --- a/platforms/mavlink/mavlink_udp_adaptor_test.go +++ b/platforms/mavlink/mavlink_udp_adaptor_test.go @@ -7,8 +7,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" mavlink "gobot.io/x/gobot/v2/platforms/mavlink/common" ) @@ -53,20 +53,20 @@ func initTestMavlinkUDPAdaptor() *UDPAdaptor { func TestMavlinkUDPAdaptor(t *testing.T) { a := initTestMavlinkUDPAdaptor() - gobottest.Assert(t, a.Port(), ":14550") + assert.Equal(t, ":14550", a.Port()) } func TestMavlinkUDPAdaptorName(t *testing.T) { a := initTestMavlinkUDPAdaptor() - gobottest.Assert(t, strings.HasPrefix(a.Name(), "Mavlink"), true) + assert.True(t, strings.HasPrefix(a.Name(), "Mavlink")) a.SetName("NewName") - gobottest.Assert(t, a.Name(), "NewName") + assert.Equal(t, "NewName", a.Name()) } func TestMavlinkUDPAdaptorConnectAndFinalize(t *testing.T) { a := initTestMavlinkUDPAdaptor() - gobottest.Assert(t, a.Connect(), nil) - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Connect()) + assert.NoError(t, a.Finalize()) } func TestMavlinkUDPAdaptorWrite(t *testing.T) { @@ -81,8 +81,8 @@ func TestMavlinkUDPAdaptorWrite(t *testing.T) { a.sock = m i, err := a.Write([]byte{0x01, 0x02, 0x03}) - gobottest.Assert(t, i, 3) - gobottest.Assert(t, err, nil) + assert.Equal(t, 3, i) + assert.NoError(t, err) } func TestMavlinkReadMAVLinkReadDefaultPacket(t *testing.T) { @@ -101,7 +101,7 @@ func TestMavlinkReadMAVLinkReadDefaultPacket(t *testing.T) { a.sock = m p, _ := a.ReadMAVLinkPacket() - gobottest.Assert(t, p.Protocol, uint8(254)) + assert.Equal(t, uint8(254), p.Protocol) } func TestMavlinkReadMAVLinkPacketReadError(t *testing.T) { @@ -136,5 +136,5 @@ func TestMavlinkReadMAVLinkPacketReadError(t *testing.T) { a.sock = m _, err := a.ReadMAVLinkPacket() - gobottest.Assert(t, err, errors.New("read error")) + assert.ErrorContains(t, err, "read error") } diff --git a/platforms/microbit/accelerometer_driver.go b/platforms/microbit/accelerometer_driver.go index b1cc4e3a9..97b26ad89 100644 --- a/platforms/microbit/accelerometer_driver.go +++ b/platforms/microbit/accelerometer_driver.go @@ -29,7 +29,7 @@ type AccelerometerData struct { const ( // BLE services - //accelerometerService = "e95d0753251d470aa062fa1922dfa9a8" + // accelerometerService = "e95d0753251d470aa062fa1922dfa9a8" // BLE characteristics accelerometerCharacteristic = "e95dca4b251d470aa062fa1922dfa9a8" @@ -85,7 +85,8 @@ func (b *AccelerometerDriver) Start() error { result := &AccelerometerData{ X: float32(a.X) / 1000.0, Y: float32(a.Y) / 1000.0, - Z: float32(a.Z) / 1000.0} + Z: float32(a.Z) / 1000.0, + } b.Publish(b.Event(Accelerometer), result) }) diff --git a/platforms/microbit/accelerometer_driver_test.go b/platforms/microbit/accelerometer_driver_test.go index 7e1786c11..2ff9fbd94 100644 --- a/platforms/microbit/accelerometer_driver_test.go +++ b/platforms/microbit/accelerometer_driver_test.go @@ -5,8 +5,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*AccelerometerDriver)(nil) @@ -18,15 +18,15 @@ func initTestAccelerometerDriver() *AccelerometerDriver { func TestAccelerometerDriver(t *testing.T) { d := initTestAccelerometerDriver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "Microbit Accelerometer"), true) + assert.True(t, strings.HasPrefix(d.Name(), "Microbit Accelerometer")) d.SetName("NewName") - gobottest.Assert(t, d.Name(), "NewName") + assert.Equal(t, "NewName", d.Name()) } func TestAccelerometerDriverStartAndHalt(t *testing.T) { d := initTestAccelerometerDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Halt()) } func TestAccelerometerDriverReadData(t *testing.T) { @@ -35,9 +35,9 @@ func TestAccelerometerDriverReadData(t *testing.T) { d := NewAccelerometerDriver(a) _ = d.Start() _ = d.On(Accelerometer, func(data interface{}) { - gobottest.Assert(t, data.(*AccelerometerData).X, float32(8.738)) - gobottest.Assert(t, data.(*AccelerometerData).Y, float32(8.995)) - gobottest.Assert(t, data.(*AccelerometerData).Z, float32(9.252)) + assert.Equal(t, float32(8.738), data.(*AccelerometerData).X) + assert.Equal(t, float32(8.995), data.(*AccelerometerData).Y) + assert.Equal(t, float32(9.252), data.(*AccelerometerData).Z) sem <- true }) diff --git a/platforms/microbit/button_driver.go b/platforms/microbit/button_driver.go index 09b17107a..3fc779329 100644 --- a/platforms/microbit/button_driver.go +++ b/platforms/microbit/button_driver.go @@ -14,7 +14,7 @@ type ButtonDriver struct { const ( // BLE services - //buttonService = "e95d9882251d470aa062fa1922dfa9a8" + // buttonService = "e95d9882251d470aa062fa1922dfa9a8" // BLE characteristics buttonACharacteristic = "e95dda90251d470aa062fa1922dfa9a8" diff --git a/platforms/microbit/button_driver_test.go b/platforms/microbit/button_driver_test.go index 007f3881c..6cc965f03 100644 --- a/platforms/microbit/button_driver_test.go +++ b/platforms/microbit/button_driver_test.go @@ -5,8 +5,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*ButtonDriver)(nil) @@ -18,15 +18,15 @@ func initTestButtonDriver() *ButtonDriver { func TestButtonDriver(t *testing.T) { d := initTestButtonDriver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "Microbit Button"), true) + assert.True(t, strings.HasPrefix(d.Name(), "Microbit Button")) d.SetName("NewName") - gobottest.Assert(t, d.Name(), "NewName") + assert.Equal(t, "NewName", d.Name()) } func TestButtonDriverStartAndHalt(t *testing.T) { d := initTestButtonDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Halt()) } func TestButtonDriverReadData(t *testing.T) { diff --git a/platforms/microbit/io_pin_driver.go b/platforms/microbit/io_pin_driver.go index b855c16bc..e9e4e51d6 100644 --- a/platforms/microbit/io_pin_driver.go +++ b/platforms/microbit/io_pin_driver.go @@ -22,7 +22,7 @@ type IOPinDriver struct { const ( // BLE services - //ioPinService = "e95d127b251d470aa062fa1922dfa9a8" + // ioPinService = "e95d127b251d470aa062fa1922dfa9a8" // BLE characteristics pinDataCharacteristic = "e95d8d00251d470aa062fa1922dfa9a8" diff --git a/platforms/microbit/io_pin_driver_test.go b/platforms/microbit/io_pin_driver_test.go index ceda71d95..11bf2e57d 100644 --- a/platforms/microbit/io_pin_driver_test.go +++ b/platforms/microbit/io_pin_driver_test.go @@ -5,19 +5,21 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" "gobot.io/x/gobot/v2/drivers/aio" "gobot.io/x/gobot/v2/drivers/gpio" - "gobot.io/x/gobot/v2/gobottest" ) // the IOPinDriver is a Driver var _ gobot.Driver = (*IOPinDriver)(nil) // that supports the DigitalReader, DigitalWriter, & AnalogReader interfaces -var _ gpio.DigitalReader = (*IOPinDriver)(nil) -var _ gpio.DigitalWriter = (*IOPinDriver)(nil) -var _ aio.AnalogReader = (*IOPinDriver)(nil) +var ( + _ gpio.DigitalReader = (*IOPinDriver)(nil) + _ gpio.DigitalWriter = (*IOPinDriver)(nil) + _ aio.AnalogReader = (*IOPinDriver)(nil) +) func initTestIOPinDriver() *IOPinDriver { d := NewIOPinDriver(NewBleTestAdaptor()) @@ -26,9 +28,9 @@ func initTestIOPinDriver() *IOPinDriver { func TestIOPinDriver(t *testing.T) { d := initTestIOPinDriver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "Microbit IO Pin"), true) + assert.True(t, strings.HasPrefix(d.Name(), "Microbit IO Pin")) d.SetName("NewName") - gobottest.Assert(t, d.Name(), "NewName") + assert.Equal(t, "NewName", d.Name()) } func TestIOPinDriverStartAndHalt(t *testing.T) { @@ -37,8 +39,8 @@ func TestIOPinDriverStartAndHalt(t *testing.T) { a.TestReadCharacteristic(func(cUUID string) ([]byte, error) { return []byte{0, 1, 1, 0}, nil }) - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Halt()) } func TestIOPinDriverStartError(t *testing.T) { @@ -47,7 +49,7 @@ func TestIOPinDriverStartError(t *testing.T) { a.TestReadCharacteristic(func(cUUID string) ([]byte, error) { return nil, errors.New("read error") }) - gobottest.Assert(t, d.Start(), errors.New("read error")) + assert.ErrorContains(t, d.Start(), "read error") } func TestIOPinDriverDigitalRead(t *testing.T) { @@ -58,10 +60,10 @@ func TestIOPinDriverDigitalRead(t *testing.T) { }) val, _ := d.DigitalRead("0") - gobottest.Assert(t, val, 1) + assert.Equal(t, 1, val) val, _ = d.DigitalRead("1") - gobottest.Assert(t, val, 0) + assert.Equal(t, 0, val) } func TestIOPinDriverDigitalReadInvalidPin(t *testing.T) { @@ -69,10 +71,10 @@ func TestIOPinDriverDigitalReadInvalidPin(t *testing.T) { d := NewIOPinDriver(a) _, err := d.DigitalRead("A3") - gobottest.Refute(t, err, nil) + assert.NotNil(t, err) _, err = d.DigitalRead("6") - gobottest.Assert(t, err, errors.New("Invalid pin.")) + assert.ErrorContains(t, err, "Invalid pin.") } func TestIOPinDriverDigitalWrite(t *testing.T) { @@ -80,15 +82,15 @@ func TestIOPinDriverDigitalWrite(t *testing.T) { d := NewIOPinDriver(a) // TODO: a better test - gobottest.Assert(t, d.DigitalWrite("0", 1), nil) + assert.NoError(t, d.DigitalWrite("0", 1)) } func TestIOPinDriverDigitalWriteInvalidPin(t *testing.T) { a := NewBleTestAdaptor() d := NewIOPinDriver(a) - gobottest.Refute(t, d.DigitalWrite("A3", 1), nil) - gobottest.Assert(t, d.DigitalWrite("6", 1), errors.New("Invalid pin.")) + assert.NotNil(t, d.DigitalWrite("A3", 1)) + assert.ErrorContains(t, d.DigitalWrite("6", 1), "Invalid pin.") } func TestIOPinDriverAnalogRead(t *testing.T) { @@ -99,10 +101,10 @@ func TestIOPinDriverAnalogRead(t *testing.T) { }) val, _ := d.AnalogRead("0") - gobottest.Assert(t, val, 0) + assert.Equal(t, 0, val) val, _ = d.AnalogRead("1") - gobottest.Assert(t, val, 128) + assert.Equal(t, 128, val) } func TestIOPinDriverAnalogReadInvalidPin(t *testing.T) { @@ -110,10 +112,10 @@ func TestIOPinDriverAnalogReadInvalidPin(t *testing.T) { d := NewIOPinDriver(a) _, err := d.AnalogRead("A3") - gobottest.Refute(t, err, nil) + assert.NotNil(t, err) _, err = d.AnalogRead("6") - gobottest.Assert(t, err, errors.New("Invalid pin.")) + assert.ErrorContains(t, err, "Invalid pin.") } func TestIOPinDriverDigitalAnalogRead(t *testing.T) { @@ -124,10 +126,10 @@ func TestIOPinDriverDigitalAnalogRead(t *testing.T) { }) val, _ := d.DigitalRead("0") - gobottest.Assert(t, val, 0) + assert.Equal(t, 0, val) val, _ = d.AnalogRead("0") - gobottest.Assert(t, val, 0) + assert.Equal(t, 0, val) } func TestIOPinDriverDigitalWriteAnalogRead(t *testing.T) { @@ -137,10 +139,10 @@ func TestIOPinDriverDigitalWriteAnalogRead(t *testing.T) { return []byte{0, 0, 1, 128, 2, 1}, nil }) - gobottest.Assert(t, d.DigitalWrite("1", 0), nil) + assert.NoError(t, d.DigitalWrite("1", 0)) val, _ := d.AnalogRead("1") - gobottest.Assert(t, val, 128) + assert.Equal(t, 128, val) } func TestIOPinDriverAnalogReadDigitalWrite(t *testing.T) { @@ -151,7 +153,7 @@ func TestIOPinDriverAnalogReadDigitalWrite(t *testing.T) { }) val, _ := d.AnalogRead("1") - gobottest.Assert(t, val, 128) + assert.Equal(t, 128, val) - gobottest.Assert(t, d.DigitalWrite("1", 0), nil) + assert.NoError(t, d.DigitalWrite("1", 0)) } diff --git a/platforms/microbit/led_driver.go b/platforms/microbit/led_driver.go index 3c9af03de..80aca8cd8 100644 --- a/platforms/microbit/led_driver.go +++ b/platforms/microbit/led_driver.go @@ -14,7 +14,7 @@ type LEDDriver struct { const ( // BLE services - //ledService = "e95dd91d251d470aa062fa1922dfa9a8" + // ledService = "e95dd91d251d470aa062fa1922dfa9a8" // BLE characteristics ledMatrixStateCharacteristic = "e95d7b77251d470aa062fa1922dfa9a8" diff --git a/platforms/microbit/led_driver_test.go b/platforms/microbit/led_driver_test.go index 9d4003c20..963759fe3 100644 --- a/platforms/microbit/led_driver_test.go +++ b/platforms/microbit/led_driver_test.go @@ -4,8 +4,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*LEDDriver)(nil) @@ -17,39 +17,39 @@ func initTestLEDDriver() *LEDDriver { func TestLEDDriver(t *testing.T) { d := initTestLEDDriver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "Microbit LED"), true) + assert.True(t, strings.HasPrefix(d.Name(), "Microbit LED")) d.SetName("NewName") - gobottest.Assert(t, d.Name(), "NewName") + assert.Equal(t, "NewName", d.Name()) } func TestLEDDriverStartAndHalt(t *testing.T) { d := initTestLEDDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Halt()) } func TestLEDDriverWriteMatrix(t *testing.T) { d := initTestLEDDriver() _ = d.Start() - gobottest.Assert(t, d.WriteMatrix([]byte{0x01, 0x02}), nil) + assert.NoError(t, d.WriteMatrix([]byte{0x01, 0x02})) } func TestLEDDriverWriteText(t *testing.T) { d := initTestLEDDriver() _ = d.Start() - gobottest.Assert(t, d.WriteText("Hello"), nil) + assert.NoError(t, d.WriteText("Hello")) } func TestLEDDriverCommands(t *testing.T) { d := initTestLEDDriver() _ = d.Start() - gobottest.Assert(t, d.Blank(), nil) - gobottest.Assert(t, d.Solid(), nil) - gobottest.Assert(t, d.UpRightArrow(), nil) - gobottest.Assert(t, d.UpLeftArrow(), nil) - gobottest.Assert(t, d.DownRightArrow(), nil) - gobottest.Assert(t, d.DownLeftArrow(), nil) - gobottest.Assert(t, d.Dimond(), nil) - gobottest.Assert(t, d.Smile(), nil) - gobottest.Assert(t, d.Wink(), nil) + assert.NoError(t, d.Blank()) + assert.NoError(t, d.Solid()) + assert.NoError(t, d.UpRightArrow()) + assert.NoError(t, d.UpLeftArrow()) + assert.NoError(t, d.DownRightArrow()) + assert.NoError(t, d.DownLeftArrow()) + assert.NoError(t, d.Dimond()) + assert.NoError(t, d.Smile()) + assert.NoError(t, d.Wink()) } diff --git a/platforms/microbit/magnetometer_driver.go b/platforms/microbit/magnetometer_driver.go index c899be683..c398eddc8 100644 --- a/platforms/microbit/magnetometer_driver.go +++ b/platforms/microbit/magnetometer_driver.go @@ -29,7 +29,7 @@ type MagnetometerData struct { const ( // BLE services - //magnetometerService = "e95df2d8251d470aa062fa1922dfa9a8" + // magnetometerService = "e95df2d8251d470aa062fa1922dfa9a8" // BLE characteristics magnetometerCharacteristic = "e95dfb11251d470aa062fa1922dfa9a8" @@ -85,7 +85,8 @@ func (b *MagnetometerDriver) Start() error { result := &MagnetometerData{ X: float32(a.X) / 1000.0, Y: float32(a.Y) / 1000.0, - Z: float32(a.Z) / 1000.0} + Z: float32(a.Z) / 1000.0, + } b.Publish(b.Event(Magnetometer), result) }) diff --git a/platforms/microbit/magnetometer_driver_test.go b/platforms/microbit/magnetometer_driver_test.go index 03ef4145f..884c9d8ae 100644 --- a/platforms/microbit/magnetometer_driver_test.go +++ b/platforms/microbit/magnetometer_driver_test.go @@ -5,8 +5,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*MagnetometerDriver)(nil) @@ -18,15 +18,15 @@ func initTestMagnetometerDriver() *MagnetometerDriver { func TestMagnetometerDriver(t *testing.T) { d := initTestMagnetometerDriver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "Microbit Magnetometer"), true) + assert.True(t, strings.HasPrefix(d.Name(), "Microbit Magnetometer")) d.SetName("NewName") - gobottest.Assert(t, d.Name(), "NewName") + assert.Equal(t, "NewName", d.Name()) } func TestMagnetometerDriverStartAndHalt(t *testing.T) { d := initTestMagnetometerDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Halt()) } func TestMagnetometerDriverReadData(t *testing.T) { @@ -35,9 +35,9 @@ func TestMagnetometerDriverReadData(t *testing.T) { d := NewMagnetometerDriver(a) _ = d.Start() _ = d.On(Magnetometer, func(data interface{}) { - gobottest.Assert(t, data.(*MagnetometerData).X, float32(8.738)) - gobottest.Assert(t, data.(*MagnetometerData).Y, float32(8.995)) - gobottest.Assert(t, data.(*MagnetometerData).Z, float32(9.252)) + assert.Equal(t, float32(8.738), data.(*MagnetometerData).X) + assert.Equal(t, float32(8.995), data.(*MagnetometerData).Y) + assert.Equal(t, float32(9.252), data.(*MagnetometerData).Z) sem <- true }) diff --git a/platforms/microbit/temperature_driver.go b/platforms/microbit/temperature_driver.go index 0e7ca7ea1..7daf96077 100644 --- a/platforms/microbit/temperature_driver.go +++ b/platforms/microbit/temperature_driver.go @@ -16,7 +16,7 @@ type TemperatureDriver struct { const ( // BLE services - //temperatureService = "e95d6100251d470aa062fa1922dfa9a8" + // temperatureService = "e95d6100251d470aa062fa1922dfa9a8" // BLE characteristics temperatureCharacteristic = "e95d9250251d470aa062fa1922dfa9a8" diff --git a/platforms/microbit/temperature_driver_test.go b/platforms/microbit/temperature_driver_test.go index 8abeef661..5bd352799 100644 --- a/platforms/microbit/temperature_driver_test.go +++ b/platforms/microbit/temperature_driver_test.go @@ -5,8 +5,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*TemperatureDriver)(nil) @@ -18,15 +18,15 @@ func initTestTemperatureDriver() *TemperatureDriver { func TestTemperatureDriver(t *testing.T) { d := initTestTemperatureDriver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "Microbit Temperature"), true) + assert.True(t, strings.HasPrefix(d.Name(), "Microbit Temperature")) d.SetName("NewName") - gobottest.Assert(t, d.Name(), "NewName") + assert.Equal(t, "NewName", d.Name()) } func TestTemperatureDriverStartAndHalt(t *testing.T) { d := initTestTemperatureDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Halt()) } func TestTemperatureDriverReadData(t *testing.T) { @@ -35,7 +35,7 @@ func TestTemperatureDriverReadData(t *testing.T) { d := NewTemperatureDriver(a) _ = d.Start() _ = d.On(Temperature, func(data interface{}) { - gobottest.Assert(t, data, int8(0x22)) + assert.Equal(t, int8(0x22), data) sem <- true }) diff --git a/platforms/mqtt/doc.go b/platforms/mqtt/doc.go index 5665a7c3f..06f3e194e 100644 --- a/platforms/mqtt/doc.go +++ b/platforms/mqtt/doc.go @@ -3,7 +3,7 @@ Package mqtt provides Gobot adaptor for the mqtt message service. Installing: - Please refer to the main [README.md](https://github.com/hybridgroup/gobot/blob/release/README.md) + Please refer to the main [README.md](https://github.com/hybridgroup/gobot/blob/release/README.md) For further information refer to mqtt README: https://github.com/hybridgroup/gobot/blob/master/platforms/mqtt/README.md diff --git a/platforms/mqtt/mqtt_adaptor.go b/platforms/mqtt/mqtt_adaptor.go index d0889e6c2..24b412445 100644 --- a/platforms/mqtt/mqtt_adaptor.go +++ b/platforms/mqtt/mqtt_adaptor.go @@ -11,10 +11,8 @@ import ( paho "github.com/eclipse/paho.mqtt.golang" ) -var ( - // ErrNilClient is returned when a client action can't be taken because the struct has no client - ErrNilClient = fmt.Errorf("no MQTT client available") -) +// ErrNilClient is returned when a client action can't be taken because the struct has no client +var ErrNilClient = fmt.Errorf("no MQTT client available") // Message is a message received from the broker. type Message paho.Message @@ -234,5 +232,8 @@ func (a *Adaptor) newTLSConfig() *tls.Config { InsecureSkipVerify: false, // Certificates = list of certs client sends to server. Certificates: certs, + // MinVersion contains the minimum TLS version that is acceptable. + // TLS 1.2 is currently used as the minimum when acting as a client. + MinVersion: tls.VersionTLS12, } } diff --git a/platforms/mqtt/mqtt_adaptor_test.go b/platforms/mqtt/mqtt_adaptor_test.go index db27ec67e..77a38b0ee 100644 --- a/platforms/mqtt/mqtt_adaptor_test.go +++ b/platforms/mqtt/mqtt_adaptor_test.go @@ -1,13 +1,12 @@ package mqtt import ( - "errors" "fmt" "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Adaptor = (*Adaptor)(nil) @@ -18,112 +17,112 @@ func initTestMqttAdaptor() *Adaptor { func TestMqttAdaptorName(t *testing.T) { a := initTestMqttAdaptor() - gobottest.Assert(t, strings.HasPrefix(a.Name(), "MQTT"), true) + assert.True(t, strings.HasPrefix(a.Name(), "MQTT")) a.SetName("NewName") - gobottest.Assert(t, a.Name(), "NewName") + assert.Equal(t, "NewName", a.Name()) } func TestMqttAdaptorPort(t *testing.T) { a := initTestMqttAdaptor() - gobottest.Assert(t, a.Port(), "tcp://localhost:1883") + assert.Equal(t, "tcp://localhost:1883", a.Port()) } func TestMqttAdaptorAutoReconnect(t *testing.T) { a := initTestMqttAdaptor() - gobottest.Assert(t, a.AutoReconnect(), false) + assert.False(t, a.AutoReconnect()) a.SetAutoReconnect(true) - gobottest.Assert(t, a.AutoReconnect(), true) + assert.True(t, a.AutoReconnect()) } func TestMqttAdaptorCleanSession(t *testing.T) { a := initTestMqttAdaptor() - gobottest.Assert(t, a.CleanSession(), true) + assert.True(t, a.CleanSession()) a.SetCleanSession(false) - gobottest.Assert(t, a.CleanSession(), false) + assert.False(t, a.CleanSession()) } func TestMqttAdaptorUseSSL(t *testing.T) { a := initTestMqttAdaptor() - gobottest.Assert(t, a.UseSSL(), false) + assert.False(t, a.UseSSL()) a.SetUseSSL(true) - gobottest.Assert(t, a.UseSSL(), true) + assert.True(t, a.UseSSL()) } func TestMqttAdaptorUseServerCert(t *testing.T) { a := initTestMqttAdaptor() - gobottest.Assert(t, a.ServerCert(), "") + assert.Equal(t, "", a.ServerCert()) a.SetServerCert("/path/to/server.cert") - gobottest.Assert(t, a.ServerCert(), "/path/to/server.cert") + assert.Equal(t, "/path/to/server.cert", a.ServerCert()) } func TestMqttAdaptorUseClientCert(t *testing.T) { a := initTestMqttAdaptor() - gobottest.Assert(t, a.ClientCert(), "") + assert.Equal(t, "", a.ClientCert()) a.SetClientCert("/path/to/client.cert") - gobottest.Assert(t, a.ClientCert(), "/path/to/client.cert") + assert.Equal(t, "/path/to/client.cert", a.ClientCert()) } func TestMqttAdaptorUseClientKey(t *testing.T) { a := initTestMqttAdaptor() - gobottest.Assert(t, a.ClientKey(), "") + assert.Equal(t, "", a.ClientKey()) a.SetClientKey("/path/to/client.key") - gobottest.Assert(t, a.ClientKey(), "/path/to/client.key") + assert.Equal(t, "/path/to/client.key", a.ClientKey()) } func TestMqttAdaptorConnectError(t *testing.T) { a := NewAdaptor("tcp://localhost:1884", "client") err := a.Connect() - gobottest.Assert(t, strings.Contains(err.Error(), "connection refused"), true) + assert.Contains(t, err.Error(), "connection refused") } func TestMqttAdaptorConnectSSLError(t *testing.T) { a := NewAdaptor("tcp://localhost:1884", "client") a.SetUseSSL(true) err := a.Connect() - gobottest.Assert(t, strings.Contains(err.Error(), "connection refused"), true) + assert.Contains(t, err.Error(), "connection refused") } func TestMqttAdaptorConnectWithAuthError(t *testing.T) { a := NewAdaptorWithAuth("xyz://localhost:1883", "client", "user", "pass") - gobottest.Assert(t, a.Connect(), errors.New("network Error : unknown protocol")) + assert.ErrorContains(t, a.Connect(), "network Error : unknown protocol") } func TestMqttAdaptorFinalize(t *testing.T) { a := initTestMqttAdaptor() - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) } func TestMqttAdaptorCannotPublishUnlessConnected(t *testing.T) { a := initTestMqttAdaptor() data := []byte("o") - gobottest.Assert(t, a.Publish("test", data), false) + assert.False(t, a.Publish("test", data)) } func TestMqttAdaptorPublishWhenConnected(t *testing.T) { a := initTestMqttAdaptor() _ = a.Connect() data := []byte("o") - gobottest.Assert(t, a.Publish("test", data), true) + assert.True(t, a.Publish("test", data)) } func TestMqttAdaptorCannotOnUnlessConnected(t *testing.T) { a := initTestMqttAdaptor() - gobottest.Assert(t, a.On("hola", func(msg Message) { + assert.False(t, a.On("hola", func(msg Message) { fmt.Println("hola") - }), false) + })) } func TestMqttAdaptorOnWhenConnected(t *testing.T) { a := initTestMqttAdaptor() _ = a.Connect() - gobottest.Assert(t, a.On("hola", func(msg Message) { + assert.True(t, a.On("hola", func(msg Message) { fmt.Println("hola") - }), true) + })) } func TestMqttAdaptorQoS(t *testing.T) { a := initTestMqttAdaptor() a.SetQoS(1) - gobottest.Assert(t, 1, a.qos) + assert.Equal(t, a.qos, 1) } diff --git a/platforms/mqtt/mqtt_driver_test.go b/platforms/mqtt/mqtt_driver_test.go index 028838db7..bf77fcdfa 100644 --- a/platforms/mqtt/mqtt_driver_test.go +++ b/platforms/mqtt/mqtt_driver_test.go @@ -4,8 +4,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*Driver)(nil) @@ -13,25 +13,25 @@ var _ gobot.Driver = (*Driver)(nil) func TestMqttDriver(t *testing.T) { d := NewDriver(initTestMqttAdaptor(), "/test/topic") - gobottest.Assert(t, strings.HasPrefix(d.Name(), "MQTT"), true) - gobottest.Assert(t, strings.HasPrefix(d.Connection().Name(), "MQTT"), true) + assert.True(t, strings.HasPrefix(d.Name(), "MQTT")) + assert.True(t, strings.HasPrefix(d.Connection().Name(), "MQTT")) - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Halt()) } func TestMqttDriverName(t *testing.T) { d := NewDriver(initTestMqttAdaptor(), "/test/topic") - gobottest.Assert(t, strings.HasPrefix(d.Name(), "MQTT"), true) + assert.True(t, strings.HasPrefix(d.Name(), "MQTT")) d.SetName("NewName") - gobottest.Assert(t, d.Name(), "NewName") + assert.Equal(t, "NewName", d.Name()) } func TestMqttDriverTopic(t *testing.T) { d := NewDriver(initTestMqttAdaptor(), "/test/topic") - gobottest.Assert(t, d.Topic(), "/test/topic") + assert.Equal(t, "/test/topic", d.Topic()) d.SetTopic("/test/newtopic") - gobottest.Assert(t, d.Topic(), "/test/newtopic") + assert.Equal(t, "/test/newtopic", d.Topic()) } func TestMqttDriverPublish(t *testing.T) { @@ -40,7 +40,7 @@ func TestMqttDriverPublish(t *testing.T) { _ = a.Connect() _ = d.Start() defer func() { _ = d.Halt() }() - gobottest.Assert(t, d.Publish([]byte{0x01, 0x02, 0x03}), true) + assert.True(t, d.Publish([]byte{0x01, 0x02, 0x03})) } func TestMqttDriverPublishError(t *testing.T) { @@ -48,5 +48,5 @@ func TestMqttDriverPublishError(t *testing.T) { d := NewDriver(a, "/test/topic") _ = d.Start() defer func() { _ = d.Halt() }() - gobottest.Assert(t, d.Publish([]byte{0x01, 0x02, 0x03}), false) + assert.False(t, d.Publish([]byte{0x01, 0x02, 0x03})) } diff --git a/platforms/nanopi/nanopi_adaptor_test.go b/platforms/nanopi/nanopi_adaptor_test.go index e6681c047..fe922621d 100644 --- a/platforms/nanopi/nanopi_adaptor_test.go +++ b/platforms/nanopi/nanopi_adaptor_test.go @@ -5,10 +5,10 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" "gobot.io/x/gobot/v2/drivers/gpio" "gobot.io/x/gobot/v2/drivers/i2c" - "gobot.io/x/gobot/v2/gobottest" "gobot.io/x/gobot/v2/system" ) @@ -18,7 +18,7 @@ const ( ) const ( - pwmDir = "/sys/devices/platform/soc/1c21400.pwm/pwm/pwmchip0/" + pwmDir = "/sys/devices/platform/soc/1c21400.pwm/pwm/pwmchip0/" //nolint:gosec // false positive pwmPwmDir = pwmDir + "pwm0/" pwmExportPath = pwmDir + "export" pwmUnexportPath = pwmDir + "unexport" @@ -47,14 +47,16 @@ var gpioMockPaths = []string{ } // make sure that this Adaptor fulfills all the required interfaces -var _ gobot.Adaptor = (*Adaptor)(nil) -var _ gobot.DigitalPinnerProvider = (*Adaptor)(nil) -var _ gobot.PWMPinnerProvider = (*Adaptor)(nil) -var _ gpio.DigitalReader = (*Adaptor)(nil) -var _ gpio.DigitalWriter = (*Adaptor)(nil) -var _ gpio.PwmWriter = (*Adaptor)(nil) -var _ gpio.ServoWriter = (*Adaptor)(nil) -var _ i2c.Connector = (*Adaptor)(nil) +var ( + _ gobot.Adaptor = (*Adaptor)(nil) + _ gobot.DigitalPinnerProvider = (*Adaptor)(nil) + _ gobot.PWMPinnerProvider = (*Adaptor)(nil) + _ gpio.DigitalReader = (*Adaptor)(nil) + _ gpio.DigitalWriter = (*Adaptor)(nil) + _ gpio.PwmWriter = (*Adaptor)(nil) + _ gpio.ServoWriter = (*Adaptor)(nil) + _ i2c.Connector = (*Adaptor)(nil) +) func preparePwmFs(fs *system.MockFilesystem) { fs.Files[pwmEnablePath].Contents = "0" @@ -74,9 +76,9 @@ func initTestAdaptorWithMockedFilesystem(mockPaths []string) (*Adaptor, *system. func TestName(t *testing.T) { a := NewNeoAdaptor() - gobottest.Assert(t, strings.HasPrefix(a.Name(), "NanoPi NEO Board"), true) + assert.True(t, strings.HasPrefix(a.Name(), "NanoPi NEO Board")) a.SetName("NewName") - gobottest.Assert(t, a.Name(), "NewName") + assert.Equal(t, "NewName", a.Name()) } func TestDigitalIO(t *testing.T) { @@ -84,14 +86,14 @@ func TestDigitalIO(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem(gpioMockPaths) _ = a.DigitalWrite("7", 1) - gobottest.Assert(t, fs.Files[gpio203Path+"value"].Contents, "1") + assert.Equal(t, "1", fs.Files[gpio203Path+"value"].Contents) fs.Files[gpio199Path+"value"].Contents = "1" i, _ := a.DigitalRead("10") - gobottest.Assert(t, i, 1) + assert.Equal(t, 1, i) - gobottest.Assert(t, a.DigitalWrite("99", 1), fmt.Errorf("'99' is not a valid id for a digital pin")) - gobottest.Assert(t, a.Finalize(), nil) + assert.ErrorContains(t, a.DigitalWrite("99", 1), "'99' is not a valid id for a digital pin") + assert.NoError(t, a.Finalize()) } func TestInvalidPWMPin(t *testing.T) { @@ -99,16 +101,16 @@ func TestInvalidPWMPin(t *testing.T) { preparePwmFs(fs) err := a.PwmWrite("666", 42) - gobottest.Assert(t, err.Error(), "'666' is not a valid id for a PWM pin") + assert.ErrorContains(t, err, "'666' is not a valid id for a PWM pin") err = a.ServoWrite("666", 120) - gobottest.Assert(t, err.Error(), "'666' is not a valid id for a PWM pin") + assert.ErrorContains(t, err, "'666' is not a valid id for a PWM pin") err = a.PwmWrite("3", 42) - gobottest.Assert(t, err.Error(), "'3' is not a valid id for a PWM pin") + assert.ErrorContains(t, err, "'3' is not a valid id for a PWM pin") err = a.ServoWrite("3", 120) - gobottest.Assert(t, err.Error(), "'3' is not a valid id for a PWM pin") + assert.ErrorContains(t, err, "'3' is not a valid id for a PWM pin") } func TestPwmWrite(t *testing.T) { @@ -116,24 +118,24 @@ func TestPwmWrite(t *testing.T) { preparePwmFs(fs) err := a.PwmWrite("PWM", 100) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) - gobottest.Assert(t, fs.Files[pwmExportPath].Contents, "0") - gobottest.Assert(t, fs.Files[pwmEnablePath].Contents, "1") - gobottest.Assert(t, fs.Files[pwmPeriodPath].Contents, fmt.Sprintf("%d", 10000000)) - gobottest.Assert(t, fs.Files[pwmDutyCyclePath].Contents, "3921568") - gobottest.Assert(t, fs.Files[pwmPolarityPath].Contents, "normal") + assert.Equal(t, "0", fs.Files[pwmExportPath].Contents) + assert.Equal(t, "1", fs.Files[pwmEnablePath].Contents) + assert.Equal(t, fmt.Sprintf("%d", 10000000), fs.Files[pwmPeriodPath].Contents) + assert.Equal(t, "3921568", fs.Files[pwmDutyCyclePath].Contents) + assert.Equal(t, "normal", fs.Files[pwmPolarityPath].Contents) err = a.ServoWrite("PWM", 0) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) - gobottest.Assert(t, fs.Files[pwmDutyCyclePath].Contents, "500000") + assert.Equal(t, "500000", fs.Files[pwmDutyCyclePath].Contents) err = a.ServoWrite("PWM", 180) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) - gobottest.Assert(t, fs.Files[pwmDutyCyclePath].Contents, "2000000") - gobottest.Assert(t, a.Finalize(), nil) + assert.Equal(t, "2000000", fs.Files[pwmDutyCyclePath].Contents) + assert.NoError(t, a.Finalize()) } func TestSetPeriod(t *testing.T) { @@ -145,25 +147,25 @@ func TestSetPeriod(t *testing.T) { // act err := a.SetPeriod("PWM", newPeriod) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files[pwmExportPath].Contents, "0") - gobottest.Assert(t, fs.Files[pwmEnablePath].Contents, "1") - gobottest.Assert(t, fs.Files[pwmPeriodPath].Contents, fmt.Sprintf("%d", newPeriod)) - gobottest.Assert(t, fs.Files[pwmDutyCyclePath].Contents, "0") - gobottest.Assert(t, fs.Files[pwmPolarityPath].Contents, "normal") + assert.NoError(t, err) + assert.Equal(t, "0", fs.Files[pwmExportPath].Contents) + assert.Equal(t, "1", fs.Files[pwmEnablePath].Contents) + assert.Equal(t, fmt.Sprintf("%d", newPeriod), fs.Files[pwmPeriodPath].Contents) + assert.Equal(t, "0", fs.Files[pwmDutyCyclePath].Contents) + assert.Equal(t, "normal", fs.Files[pwmPolarityPath].Contents) // arrange test for automatic adjustment of duty cycle to lower value err = a.PwmWrite("PWM", 127) // 127 is a little bit smaller than 50% of period - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files[pwmDutyCyclePath].Contents, fmt.Sprintf("%d", 1270000)) + assert.NoError(t, err) + assert.Equal(t, fmt.Sprintf("%d", 1270000), fs.Files[pwmDutyCyclePath].Contents) newPeriod = newPeriod / 10 // act err = a.SetPeriod("PWM", newPeriod) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files[pwmDutyCyclePath].Contents, fmt.Sprintf("%d", 127000)) + assert.NoError(t, err) + assert.Equal(t, fmt.Sprintf("%d", 127000), fs.Files[pwmDutyCyclePath].Contents) // arrange test for automatic adjustment of duty cycle to higher value newPeriod = newPeriod * 20 @@ -172,46 +174,46 @@ func TestSetPeriod(t *testing.T) { err = a.SetPeriod("PWM", newPeriod) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files[pwmDutyCyclePath].Contents, fmt.Sprintf("%d", 2540000)) + assert.NoError(t, err) + assert.Equal(t, fmt.Sprintf("%d", 2540000), fs.Files[pwmDutyCyclePath].Contents) } func TestFinalizeErrorAfterGPIO(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem(gpioMockPaths) - gobottest.Assert(t, a.DigitalWrite("7", 1), nil) + assert.NoError(t, a.DigitalWrite("7", 1)) fs.WithWriteError = true err := a.Finalize() - gobottest.Assert(t, strings.Contains(err.Error(), "write error"), true) + assert.Contains(t, err.Error(), "write error") } func TestFinalizeErrorAfterPWM(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem(pwmMockPaths) preparePwmFs(fs) - gobottest.Assert(t, a.PwmWrite("PWM", 1), nil) + assert.NoError(t, a.PwmWrite("PWM", 1)) fs.WithWriteError = true err := a.Finalize() - gobottest.Assert(t, strings.Contains(err.Error(), "write error"), true) + assert.Contains(t, err.Error(), "write error") } func TestSpiDefaultValues(t *testing.T) { a := NewNeoAdaptor() - gobottest.Assert(t, a.SpiDefaultBusNumber(), 0) - gobottest.Assert(t, a.SpiDefaultChipNumber(), 0) - gobottest.Assert(t, a.SpiDefaultMode(), 0) - gobottest.Assert(t, a.SpiDefaultBitCount(), 8) - gobottest.Assert(t, a.SpiDefaultMaxSpeed(), int64(500000)) + assert.Equal(t, 0, a.SpiDefaultBusNumber()) + assert.Equal(t, 0, a.SpiDefaultChipNumber()) + assert.Equal(t, 0, a.SpiDefaultMode()) + assert.Equal(t, 8, a.SpiDefaultBitCount()) + assert.Equal(t, int64(500000), a.SpiDefaultMaxSpeed()) } func TestI2cDefaultBus(t *testing.T) { a := NewNeoAdaptor() - gobottest.Assert(t, a.DefaultI2cBus(), 0) + assert.Equal(t, 0, a.DefaultI2cBus()) } func TestI2cFinalizeWithErrors(t *testing.T) { @@ -219,20 +221,20 @@ func TestI2cFinalizeWithErrors(t *testing.T) { a := NewNeoAdaptor() a.sys.UseMockSyscall() fs := a.sys.UseMockFilesystem([]string{"/dev/i2c-1"}) - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) con, err := a.GetI2cConnection(0xff, 1) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) _, err = con.Write([]byte{0xbf}) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) fs.WithCloseError = true // act err = a.Finalize() // assert - gobottest.Assert(t, strings.Contains(err.Error(), "close error"), true) + assert.Contains(t, err.Error(), "close error") } func Test_validateSpiBusNumber(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { busNr int wantErr error }{ @@ -255,13 +257,13 @@ func Test_validateSpiBusNumber(t *testing.T) { // act err := a.validateSpiBusNumber(tc.busNr) // assert - gobottest.Assert(t, err, tc.wantErr) + assert.Equal(t, tc.wantErr, err) }) } } func Test_validateI2cBusNumber(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { busNr int wantErr error }{ @@ -290,13 +292,13 @@ func Test_validateI2cBusNumber(t *testing.T) { // act err := a.validateI2cBusNumber(tc.busNr) // assert - gobottest.Assert(t, err, tc.wantErr) + assert.Equal(t, tc.wantErr, err) }) } } func Test_translateDigitalPin(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { access string pin string wantChip string @@ -330,16 +332,16 @@ func Test_translateDigitalPin(t *testing.T) { // act chip, line, err := a.translateDigitalPin(tc.pin) // assert - gobottest.Assert(t, err, tc.wantErr) - gobottest.Assert(t, chip, tc.wantChip) - gobottest.Assert(t, line, tc.wantLine) + assert.Equal(t, tc.wantErr, err) + assert.Equal(t, tc.wantChip, chip) + assert.Equal(t, tc.wantLine, line) }) } } func Test_translatePWMPin(t *testing.T) { basePaths := []string{"/sys/devices/platform/soc/1c21400.pwm/pwm/"} - var tests = map[string]struct { + tests := map[string]struct { pin string chip string wantDir string @@ -370,9 +372,9 @@ func Test_translatePWMPin(t *testing.T) { // act dir, channel, err := a.translatePWMPin(tc.pin) // assert - gobottest.Assert(t, err, tc.wantErr) - gobottest.Assert(t, dir, tc.wantDir) - gobottest.Assert(t, channel, tc.wantChannel) + assert.Equal(t, tc.wantErr, err) + assert.Equal(t, tc.wantDir, dir) + assert.Equal(t, tc.wantChannel, channel) }) } } diff --git a/platforms/nats/doc.go b/platforms/nats/doc.go index 3d3bcabd4..5628b9695 100644 --- a/platforms/nats/doc.go +++ b/platforms/nats/doc.go @@ -2,7 +2,7 @@ Package nats provides Gobot adaptor for the nats message service. Installing: - Please refer to the main [README.md](https://github.com/hybridgroup/gobot/blob/release/README.md) + Please refer to the main [README.md](https://github.com/hybridgroup/gobot/blob/release/README.md) For further information refer to nats README: https://github.com/hybridgroup/gobot/blob/master/platforms/nats/README.md diff --git a/platforms/nats/nats_adaptor_test.go b/platforms/nats/nats_adaptor_test.go index 469ec6f2b..feccd0a94 100644 --- a/platforms/nats/nats_adaptor_test.go +++ b/platforms/nats/nats_adaptor_test.go @@ -1,15 +1,14 @@ package nats import ( - "errors" "fmt" "log" "strings" "testing" "github.com/nats-io/nats.go" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Adaptor = (*Adaptor)(nil) @@ -53,55 +52,55 @@ func initTestNatsAdaptorTLS(options ...nats.Option) *Adaptor { func TestNatsAdaptorName(t *testing.T) { a := initTestNatsAdaptor() - gobottest.Assert(t, strings.HasPrefix(a.Name(), "NATS"), true) + assert.True(t, strings.HasPrefix(a.Name(), "NATS")) a.SetName("NewName") - gobottest.Assert(t, a.Name(), "NewName") + assert.Equal(t, "NewName", a.Name()) } func TestNatsAdaptorReturnsHost(t *testing.T) { a := initTestNatsAdaptor() - gobottest.Assert(t, a.Host, "nats://localhost:4222") + assert.Equal(t, "nats://localhost:4222", a.Host) } func TestNatsAdaptorWithAuth(t *testing.T) { a := initTestNatsAdaptorWithAuth() - gobottest.Assert(t, a.username, "user") - gobottest.Assert(t, a.password, "pass") + assert.Equal(t, "user", a.username) + assert.Equal(t, "pass", a.password) } func TestNatsAdapterSetsRootCAs(t *testing.T) { a := initTestNatsAdaptorTLS(nats.RootCAs("test_certs/catest.pem")) - gobottest.Assert(t, a.Host, "tls://localhost:4242") + assert.Equal(t, "tls://localhost:4242", a.Host) _ = a.Connect() o := a.client.Opts casPool, err := o.RootCAsCB() - gobottest.Assert(t, err, nil) - gobottest.Refute(t, casPool, nil) - gobottest.Assert(t, o.Secure, true) + assert.NoError(t, err) + assert.NotNil(t, casPool) + assert.True(t, o.Secure) } func TestNatsAdapterSetsClientCerts(t *testing.T) { a := initTestNatsAdaptorTLS(nats.ClientCert("test_certs/client-cert.pem", "test_certs/client-key.pem")) - gobottest.Assert(t, a.Host, "tls://localhost:4242") + assert.Equal(t, "tls://localhost:4242", a.Host) _ = a.Connect() cert, err := a.client.Opts.TLSCertCB() - gobottest.Assert(t, err, nil) - gobottest.Refute(t, cert, nil) - gobottest.Refute(t, cert.Leaf, nil) - gobottest.Assert(t, a.client.Opts.Secure, true) + assert.NoError(t, err) + assert.NotNil(t, cert) + assert.NotNil(t, cert.Leaf) + assert.True(t, a.client.Opts.Secure) } func TestNatsAdapterSetsClientCertsWithUserInfo(t *testing.T) { a := initTestNatsAdaptorTLS(nats.ClientCert("test_certs/client-cert.pem", "test_certs/client-key.pem"), nats.UserInfo("test", "testwd")) - gobottest.Assert(t, a.Host, "tls://localhost:4242") + assert.Equal(t, "tls://localhost:4242", a.Host) _ = a.Connect() cert, err := a.client.Opts.TLSCertCB() - gobottest.Assert(t, err, nil) - gobottest.Refute(t, cert, nil) - gobottest.Refute(t, cert.Leaf, nil) - gobottest.Assert(t, a.client.Opts.Secure, true) - gobottest.Assert(t, a.client.Opts.User, "test") - gobottest.Assert(t, a.client.Opts.Password, "testwd") + assert.NoError(t, err) + assert.NotNil(t, cert) + assert.NotNil(t, cert.Leaf) + assert.True(t, a.client.Opts.Secure) + assert.Equal(t, "test", a.client.Opts.User) + assert.Equal(t, "testwd", a.client.Opts.Password) } // TODO: implement this test without requiring actual server connection @@ -110,7 +109,7 @@ func TestNatsAdaptorPublishWhenConnected(t *testing.T) { a := initTestNatsAdaptor() _ = a.Connect() data := []byte("o") - gobottest.Assert(t, a.Publish("test", data), true) + assert.True(t, a.Publish("test", data)) } // TODO: implement this test without requiring actual server connection @@ -118,9 +117,9 @@ func TestNatsAdaptorOnWhenConnected(t *testing.T) { t.Skip("TODO: implement this test without requiring actual server connection") a := initTestNatsAdaptor() _ = a.Connect() - gobottest.Assert(t, a.On("hola", func(msg Message) { + assert.True(t, a.On("hola", func(msg Message) { fmt.Println("hola") - }), true) + })) } // TODO: implement this test without requiring actual server connection @@ -129,7 +128,7 @@ func TestNatsAdaptorPublishWhenConnectedWithAuth(t *testing.T) { a := NewAdaptorWithAuth("localhost:4222", 49999, "test", "testwd") _ = a.Connect() data := []byte("o") - gobottest.Assert(t, a.Publish("test", data), true) + assert.True(t, a.Publish("test", data)) } // TODO: implement this test without requiring actual server connection @@ -138,9 +137,9 @@ func TestNatsAdaptorOnWhenConnectedWithAuth(t *testing.T) { log.Println("###not skipped###") a := NewAdaptorWithAuth("localhost:4222", 59999, "test", "testwd") _ = a.Connect() - gobottest.Assert(t, a.On("hola", func(msg Message) { + assert.True(t, a.On("hola", func(msg Message) { fmt.Println("hola") - }), true) + })) } func TestNatsAdaptorFailedConnect(t *testing.T) { @@ -149,23 +148,23 @@ func TestNatsAdaptorFailedConnect(t *testing.T) { if err != nil && strings.Contains(err.Error(), "cannot assign requested address") { t.Skip("FLAKY: Can not test, because IP or port is in use.") } - gobottest.Assert(t, err, errors.New("nats: no servers available for connection")) + assert.ErrorContains(t, err, "nats: no servers available for connection") } func TestNatsAdaptorFinalize(t *testing.T) { a := NewAdaptor("localhost:9999", 79999) - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) } func TestNatsAdaptorCannotPublishUnlessConnected(t *testing.T) { a := NewAdaptor("localhost:9999", 89999) data := []byte("o") - gobottest.Assert(t, a.Publish("test", data), false) + assert.False(t, a.Publish("test", data)) } func TestNatsAdaptorCannotOnUnlessConnected(t *testing.T) { a := NewAdaptor("localhost:9999", 99999) - gobottest.Assert(t, a.On("hola", func(msg Message) { + assert.False(t, a.On("hola", func(msg Message) { fmt.Println("hola") - }), false) + })) } diff --git a/platforms/nats/nats_driver_test.go b/platforms/nats/nats_driver_test.go index 2725df02f..d9a4a970b 100644 --- a/platforms/nats/nats_driver_test.go +++ b/platforms/nats/nats_driver_test.go @@ -4,8 +4,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*Driver)(nil) @@ -13,23 +13,23 @@ var _ gobot.Driver = (*Driver)(nil) func TestNatsDriver(t *testing.T) { d := NewDriver(initTestNatsAdaptor(), "/test/topic") - gobottest.Assert(t, strings.HasPrefix(d.Name(), "NATS"), true) - gobottest.Assert(t, strings.HasPrefix(d.Connection().Name(), "NATS"), true) - gobottest.Refute(t, d.adaptor(), nil) + assert.True(t, strings.HasPrefix(d.Name(), "NATS")) + assert.True(t, strings.HasPrefix(d.Connection().Name(), "NATS")) + assert.NotNil(t, d.adaptor()) - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Halt()) } func TestNatsDriverName(t *testing.T) { d := NewDriver(initTestNatsAdaptor(), "/test/topic") - gobottest.Assert(t, strings.HasPrefix(d.Name(), "NATS"), true) + assert.True(t, strings.HasPrefix(d.Name(), "NATS")) d.SetName("NewName") - gobottest.Assert(t, d.Name(), "NewName") + assert.Equal(t, "NewName", d.Name()) } func TestNatsDriverTopic(t *testing.T) { d := NewDriver(initTestNatsAdaptor(), "/test/topic") d.SetTopic("interestingtopic") - gobottest.Assert(t, d.Topic(), "interestingtopic") + assert.Equal(t, "interestingtopic", d.Topic()) } diff --git a/platforms/neurosky/neurosky_adaptor_test.go b/platforms/neurosky/neurosky_adaptor_test.go index 74237ec7a..68528c391 100644 --- a/platforms/neurosky/neurosky_adaptor_test.go +++ b/platforms/neurosky/neurosky_adaptor_test.go @@ -7,8 +7,8 @@ import ( "sync" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Adaptor = (*Adaptor)(nil) @@ -57,24 +57,24 @@ func initTestNeuroskyAdaptor() *Adaptor { func TestNeuroskyAdaptor(t *testing.T) { a := NewAdaptor("/dev/null") - gobottest.Assert(t, a.Port(), "/dev/null") + assert.Equal(t, "/dev/null", a.Port()) } func TestNeuroskyAdaptorName(t *testing.T) { a := NewAdaptor("/dev/null") - gobottest.Assert(t, strings.HasPrefix(a.Name(), "Neurosky"), true) + assert.True(t, strings.HasPrefix(a.Name(), "Neurosky")) a.SetName("NewName") - gobottest.Assert(t, a.Name(), "NewName") + assert.Equal(t, "NewName", a.Name()) } func TestNeuroskyAdaptorConnect(t *testing.T) { a := initTestNeuroskyAdaptor() - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) a.connect = func(n *Adaptor) (io.ReadWriteCloser, error) { return nil, errors.New("connection error") } - gobottest.Assert(t, a.Connect(), errors.New("connection error")) + assert.ErrorContains(t, a.Connect(), "connection error") } func TestNeuroskyAdaptorFinalize(t *testing.T) { @@ -84,9 +84,9 @@ func TestNeuroskyAdaptorFinalize(t *testing.T) { return rwc, nil } _ = a.Connect() - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) rwc.CloseError(errors.New("close error")) _ = a.Connect() - gobottest.Assert(t, a.Finalize(), errors.New("close error")) + assert.ErrorContains(t, a.Finalize(), "close error") } diff --git a/platforms/neurosky/neurosky_driver.go b/platforms/neurosky/neurosky_driver.go index a09328ea5..1ebe5198f 100644 --- a/platforms/neurosky/neurosky_driver.go +++ b/platforms/neurosky/neurosky_driver.go @@ -151,7 +151,7 @@ func (n *Driver) parse(buf *bytes.Buffer) error { if _, err := buf.Read(payload); err != nil { return err } - //checksum, _ := buf.ReadByte() + // checksum, _ := buf.ReadByte() buf.Next(1) if err := n.parsePacket(bytes.NewBuffer(payload)); err != nil { panic(err) @@ -183,7 +183,7 @@ func (n *Driver) parsePacket(buf *bytes.Buffer) error { n.Publish(n.Event("blink"), ret) case CodeWave: buf.Next(1) - var ret = make([]byte, 2) + ret := make([]byte, 2) if _, err := buf.Read(ret); err != nil { return err } diff --git a/platforms/neurosky/neurosky_driver_test.go b/platforms/neurosky/neurosky_driver_test.go index 9f83f5387..d5d3cfee5 100644 --- a/platforms/neurosky/neurosky_driver_test.go +++ b/platforms/neurosky/neurosky_driver_test.go @@ -8,8 +8,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*Driver)(nil) @@ -25,14 +25,14 @@ func initTestNeuroskyDriver() *Driver { func TestNeuroskyDriver(t *testing.T) { d := initTestNeuroskyDriver() - gobottest.Refute(t, d.Connection(), nil) + assert.NotNil(t, d.Connection()) } func TestNeuroskyDriverName(t *testing.T) { d := initTestNeuroskyDriver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "Neurosky"), true) + assert.True(t, strings.HasPrefix(d.Name(), "Neurosky")) d.SetName("NewName") - gobottest.Assert(t, d.Name(), "NewName") + assert.Equal(t, "NewName", d.Name()) } func TestNeuroskyDriverStart(t *testing.T) { @@ -48,11 +48,11 @@ func TestNeuroskyDriverStart(t *testing.T) { d := NewDriver(a) e := errors.New("read error") _ = d.Once(d.Event(Error), func(data interface{}) { - gobottest.Assert(t, data.(error), e) + assert.Equal(t, e, data.(error)) sem <- true }) - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) time.Sleep(50 * time.Millisecond) rwc.ReadError(e) @@ -69,7 +69,7 @@ func TestNeuroskyDriverStart(t *testing.T) { func TestNeuroskyDriverHalt(t *testing.T) { d := initTestNeuroskyDriver() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestNeuroskyDriverParse(t *testing.T) { @@ -99,7 +99,7 @@ func TestNeuroskyDriverParse(t *testing.T) { }() _ = d.On(d.Event(Signal), func(data interface{}) { - gobottest.Assert(t, data.(byte), byte(100)) + assert.Equal(t, byte(100), data.(byte)) sem <- true }) @@ -112,7 +112,7 @@ func TestNeuroskyDriverParse(t *testing.T) { }() _ = d.On(d.Event(Attention), func(data interface{}) { - gobottest.Assert(t, data.(byte), byte(40)) + assert.Equal(t, byte(40), data.(byte)) sem <- true }) @@ -125,7 +125,7 @@ func TestNeuroskyDriverParse(t *testing.T) { }() _ = d.On(d.Event(Meditation), func(data interface{}) { - gobottest.Assert(t, data.(byte), byte(60)) + assert.Equal(t, byte(60), data.(byte)) sem <- true }) @@ -138,7 +138,7 @@ func TestNeuroskyDriverParse(t *testing.T) { }() _ = d.On(d.Event(Blink), func(data interface{}) { - gobottest.Assert(t, data.(byte), byte(150)) + assert.Equal(t, byte(150), data.(byte)) sem <- true }) @@ -151,7 +151,7 @@ func TestNeuroskyDriverParse(t *testing.T) { }() _ = d.On(d.Event(Wave), func(data interface{}) { - gobottest.Assert(t, data.(int16), int16(16401)) + assert.Equal(t, int16(16401), data.(int16)) sem <- true }) @@ -160,14 +160,15 @@ func TestNeuroskyDriverParse(t *testing.T) { // CodeAsicEEG go func() { time.Sleep(5 * time.Millisecond) - _ = d.parse(bytes.NewBuffer([]byte{0xAA, 0xAA, 30, 0x83, 24, 1, 121, 89, 0, + _ = d.parse(bytes.NewBuffer([]byte{ + 0xAA, 0xAA, 30, 0x83, 24, 1, 121, 89, 0, 97, 26, 0, 30, 189, 0, 57, 1, 0, 62, 160, 0, 31, 127, 0, 18, 207, 0, 13, - 108, 0x00})) + 108, 0x00, + })) }() _ = d.On(d.Event(EEG), func(data interface{}) { - gobottest.Assert(t, - data.(EEGData), + assert.Equal(t, EEGData{ Delta: 1573241, Theta: 5832801, @@ -177,7 +178,8 @@ func TestNeuroskyDriverParse(t *testing.T) { HiBeta: 10485791, LoGamma: 8323090, MidGamma: 13565965, - }) + }, + data.(EEGData)) sem <- true }) <-sem diff --git a/platforms/opencv/camera_driver_test.go b/platforms/opencv/camera_driver_test.go index dd3ae7bf8..973f36cf2 100644 --- a/platforms/opencv/camera_driver_test.go +++ b/platforms/opencv/camera_driver_test.go @@ -5,8 +5,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*CameraDriver)(nil) @@ -22,21 +22,21 @@ func initTestCameraDriver() *CameraDriver { func TestCameraDriver(t *testing.T) { d := initTestCameraDriver() - gobottest.Assert(t, d.Name(), "Camera") - gobottest.Assert(t, d.Connection(), (gobot.Connection)(nil)) + assert.Equal(t, "Camera", d.Name()) + assert.Equal(t, (gobot.Connection)(nil), d.Connection()) } func TestCameraDriverName(t *testing.T) { d := initTestCameraDriver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "Camera"), true) + assert.True(t, strings.HasPrefix(d.Name(), "Camera")) d.SetName("NewName") - gobottest.Assert(t, d.Name(), "NewName") + assert.Equal(t, "NewName", d.Name()) } func TestCameraDriverStart(t *testing.T) { sem := make(chan bool) d := initTestCameraDriver() - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) d.On(d.Event("frame"), func(data interface{}) { sem <- true }) @@ -47,13 +47,13 @@ func TestCameraDriverStart(t *testing.T) { } d = NewCameraDriver("") - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) d = NewCameraDriver(true) - gobottest.Refute(t, d.Start(), nil) + assert.NotNil(t, d.Start()) } func TestCameraDriverHalt(t *testing.T) { d := initTestCameraDriver() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } diff --git a/platforms/opencv/utils_test.go b/platforms/opencv/utils_test.go index b89a95c00..924dd53d7 100644 --- a/platforms/opencv/utils_test.go +++ b/platforms/opencv/utils_test.go @@ -5,7 +5,7 @@ import ( "runtime" "testing" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" "gocv.io/x/gocv" ) @@ -13,6 +13,6 @@ func TestUtils(t *testing.T) { _, currentfile, _, _ := runtime.Caller(0) image := gocv.IMRead(path.Join(path.Dir(currentfile), "lena-256x256.jpg"), gocv.IMReadColor) rect := DetectObjects("haarcascade_frontalface_alt.xml", image) - gobottest.Refute(t, len(rect), 0) + assert.NotEqual(t, 0, len(rect)) DrawRectangles(image, rect, 0, 0, 0, 0) } diff --git a/platforms/opencv/window_driver_test.go b/platforms/opencv/window_driver_test.go index 9a1127744..bc652ccb9 100644 --- a/platforms/opencv/window_driver_test.go +++ b/platforms/opencv/window_driver_test.go @@ -6,8 +6,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" "gocv.io/x/gocv" ) @@ -20,25 +20,25 @@ func initTestWindowDriver() *WindowDriver { func TestWindowDriver(t *testing.T) { d := initTestWindowDriver() - gobottest.Assert(t, d.Name(), "Window") - gobottest.Assert(t, d.Connection(), (gobot.Connection)(nil)) + assert.Equal(t, "Window", d.Name()) + assert.Equal(t, (gobot.Connection)(nil), d.Connection()) } func TestWindowDriverName(t *testing.T) { d := initTestWindowDriver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "Window"), true) + assert.True(t, strings.HasPrefix(d.Name(), "Window")) d.SetName("NewName") - gobottest.Assert(t, d.Name(), "NewName") + assert.Equal(t, "NewName", d.Name()) } func TestWindowDriverStart(t *testing.T) { d := initTestWindowDriver() - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestWindowDriverHalt(t *testing.T) { d := initTestWindowDriver() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestWindowDriverShowImage(t *testing.T) { diff --git a/platforms/parrot/ardrone/ardrone_adaptor_test.go b/platforms/parrot/ardrone/ardrone_adaptor_test.go index beb8ffe89..90bed54ef 100644 --- a/platforms/parrot/ardrone/ardrone_adaptor_test.go +++ b/platforms/parrot/ardrone/ardrone_adaptor_test.go @@ -5,8 +5,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Adaptor = (*Adaptor)(nil) @@ -21,30 +21,30 @@ func initTestArdroneAdaptor() *Adaptor { func TestArdroneAdaptor(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, a.config.Ip, "192.168.1.1") + assert.Equal(t, "192.168.1.1", a.config.Ip) a = NewAdaptor("192.168.100.100") - gobottest.Assert(t, a.config.Ip, "192.168.100.100") + assert.Equal(t, "192.168.100.100", a.config.Ip) } func TestArdroneAdaptorConnect(t *testing.T) { a := initTestArdroneAdaptor() - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) a.connect = func(a *Adaptor) (drone, error) { return nil, errors.New("connection error") } - gobottest.Assert(t, a.Connect(), errors.New("connection error")) + assert.ErrorContains(t, a.Connect(), "connection error") } func TestArdroneAdaptorName(t *testing.T) { a := initTestArdroneAdaptor() - gobottest.Assert(t, strings.HasPrefix(a.Name(), "ARDrone"), true) + assert.True(t, strings.HasPrefix(a.Name(), "ARDrone")) a.SetName("NewName") - gobottest.Assert(t, a.Name(), "NewName") + assert.Equal(t, "NewName", a.Name()) } func TestArdroneAdaptorFinalize(t *testing.T) { a := initTestArdroneAdaptor() - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) } diff --git a/platforms/parrot/ardrone/ardrone_driver_test.go b/platforms/parrot/ardrone/ardrone_driver_test.go index dfdf6e26c..2d35a189b 100644 --- a/platforms/parrot/ardrone/ardrone_driver_test.go +++ b/platforms/parrot/ardrone/ardrone_driver_test.go @@ -3,8 +3,8 @@ package ardrone import ( "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*Driver)(nil) @@ -22,25 +22,26 @@ func initTestArdroneDriver() *Driver { func TestArdroneDriver(t *testing.T) { d := initTestArdroneDriver() - gobottest.Assert(t, d.Name(), "mydrone") + assert.Equal(t, "mydrone", d.Name()) } func TestArdroneDriverName(t *testing.T) { d := initTestArdroneDriver() - gobottest.Assert(t, d.Name(), "mydrone") + assert.Equal(t, "mydrone", d.Name()) d.SetName("NewName") - gobottest.Assert(t, d.Name(), "NewName") + assert.Equal(t, "NewName", d.Name()) } func TestArdroneDriverStart(t *testing.T) { d := initTestArdroneDriver() - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestArdroneDriverHalt(t *testing.T) { d := initTestArdroneDriver() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } + func TestArdroneDriverTakeOff(t *testing.T) { d := initTestArdroneDriver() d.TakeOff() diff --git a/platforms/parrot/ardrone/pitch_test.go b/platforms/parrot/ardrone/pitch_test.go index 97e3ac9ae..c4f5870c2 100644 --- a/platforms/parrot/ardrone/pitch_test.go +++ b/platforms/parrot/ardrone/pitch_test.go @@ -3,17 +3,17 @@ package ardrone import ( "testing" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) func TestArdroneValidatePitchWhenEqualOffset(t *testing.T) { - gobottest.Assert(t, ValidatePitch(32767.0, 32767.0), 1.0) + assert.Equal(t, 1.0, ValidatePitch(32767.0, 32767.0)) } func TestArdroneValidatePitchWhenTiny(t *testing.T) { - gobottest.Assert(t, ValidatePitch(1.1, 32767.0), 0.0) + assert.Equal(t, 0.0, ValidatePitch(1.1, 32767.0)) } func TestArdroneValidatePitchWhenCentered(t *testing.T) { - gobottest.Assert(t, ValidatePitch(16383.5, 32767.0), 0.5) + assert.Equal(t, 0.5, ValidatePitch(16383.5, 32767.0)) } diff --git a/platforms/parrot/bebop/bebop_adaptor_test.go b/platforms/parrot/bebop/bebop_adaptor_test.go index 7faf839ca..6c5e0301c 100644 --- a/platforms/parrot/bebop/bebop_adaptor_test.go +++ b/platforms/parrot/bebop/bebop_adaptor_test.go @@ -5,8 +5,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Adaptor = (*Adaptor)(nil) @@ -22,23 +22,23 @@ func initTestBebopAdaptor() *Adaptor { func TestBebopAdaptorName(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, strings.HasPrefix(a.Name(), "Bebop"), true) + assert.True(t, strings.HasPrefix(a.Name(), "Bebop")) a.SetName("NewName") - gobottest.Assert(t, a.Name(), "NewName") + assert.Equal(t, "NewName", a.Name()) } func TestBebopAdaptorConnect(t *testing.T) { a := initTestBebopAdaptor() - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) a.connect = func(a *Adaptor) error { return errors.New("connection error") } - gobottest.Assert(t, a.Connect(), errors.New("connection error")) + assert.ErrorContains(t, a.Connect(), "connection error") } func TestBebopAdaptorFinalize(t *testing.T) { a := initTestBebopAdaptor() _ = a.Connect() - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) } diff --git a/platforms/parrot/bebop/bebop_driver_test.go b/platforms/parrot/bebop/bebop_driver_test.go index 0565114ba..6685eb650 100644 --- a/platforms/parrot/bebop/bebop_driver_test.go +++ b/platforms/parrot/bebop/bebop_driver_test.go @@ -4,8 +4,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*Driver)(nil) @@ -13,7 +13,7 @@ var _ gobot.Driver = (*Driver)(nil) func TestBebopDriverName(t *testing.T) { a := initTestBebopAdaptor() d := NewDriver(a) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "Bebop"), true) + assert.True(t, strings.HasPrefix(d.Name(), "Bebop")) d.SetName("NewName") - gobottest.Assert(t, d.Name(), "NewName") + assert.Equal(t, "NewName", d.Name()) } diff --git a/platforms/parrot/bebop/client/client.go b/platforms/parrot/bebop/client/client.go index 50c76bcbf..9d54c183b 100644 --- a/platforms/parrot/bebop/client/client.go +++ b/platforms/parrot/bebop/client/client.go @@ -202,9 +202,9 @@ func New() *Bebop { } } -func (b *Bebop) write(buf []byte) (int, error) { +func (b *Bebop) write(buf []byte) error { b.writeChan <- buf - return 0, nil + return nil } func (b *Bebop) Discover() error { @@ -248,13 +248,11 @@ func (b *Bebop) Discover() error { func (b *Bebop) Connect() error { err := b.Discover() - if err != nil { return err } c2daddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", b.IP, b.C2dPort)) - if err != nil { return err } @@ -266,7 +264,6 @@ func (b *Bebop) Connect() error { } d2caddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf(":%d", b.D2cPort)) - if err != nil { return err } @@ -278,7 +275,6 @@ func (b *Bebop) Connect() error { go func() { for { _, err := b.c2dClient.Write(<-b.writeChan) - if err != nil { fmt.Println(err) } @@ -302,8 +298,7 @@ func (b *Bebop) Connect() error { // wait a little bit so that there is enough time to get some ACKs time.Sleep(500 * time.Millisecond) for { - _, err := b.write(b.generatePcmd().Bytes()) - if err != nil { + if err := b.write(b.generatePcmd().Bytes()); err != nil { fmt.Println("pcmd c2dClient.Write", err) } time.Sleep(25 * time.Millisecond) @@ -337,8 +332,7 @@ func (b *Bebop) FlatTrim() error { cmd.Write(tmp.Bytes()) - _, err := b.write(b.networkFrameGenerator(cmd, ARNETWORKAL_FRAME_TYPE_DATA, BD_NET_CD_NONACK_ID).Bytes()) - return err + return b.write(b.networkFrameGenerator(cmd, ARNETWORKAL_FRAME_TYPE_DATA, BD_NET_CD_NONACK_ID).Bytes()) } func (b *Bebop) GenerateAllStates() error { @@ -358,8 +352,7 @@ func (b *Bebop) GenerateAllStates() error { cmd.Write(tmp.Bytes()) - _, err := b.write(b.networkFrameGenerator(cmd, ARNETWORKAL_FRAME_TYPE_DATA, BD_NET_CD_NONACK_ID).Bytes()) - return err + return b.write(b.networkFrameGenerator(cmd, ARNETWORKAL_FRAME_TYPE_DATA, BD_NET_CD_NONACK_ID).Bytes()) } func (b *Bebop) TakeOff() error { @@ -379,8 +372,7 @@ func (b *Bebop) TakeOff() error { cmd.Write(tmp.Bytes()) - _, err := b.write(b.networkFrameGenerator(cmd, ARNETWORKAL_FRAME_TYPE_DATA, BD_NET_CD_NONACK_ID).Bytes()) - return err + return b.write(b.networkFrameGenerator(cmd, ARNETWORKAL_FRAME_TYPE_DATA, BD_NET_CD_NONACK_ID).Bytes()) } func (b *Bebop) Land() error { @@ -400,8 +392,7 @@ func (b *Bebop) Land() error { cmd.Write(tmp.Bytes()) - _, err := b.write(b.networkFrameGenerator(cmd, ARNETWORKAL_FRAME_TYPE_DATA, BD_NET_CD_NONACK_ID).Bytes()) - return err + return b.write(b.networkFrameGenerator(cmd, ARNETWORKAL_FRAME_TYPE_DATA, BD_NET_CD_NONACK_ID).Bytes()) } func (b *Bebop) Up(val int) error { @@ -558,9 +549,7 @@ func (b *Bebop) packetReceiver(buf []byte) { // if frame.Type == int(ARNETWORKAL_FRAME_TYPE_DATA_WITH_ACK) { ack := b.createAck(frame).Bytes() - _, err := b.write(ack) - - if err != nil { + if err := b.write(ack); err != nil { fmt.Println("ARNETWORKAL_FRAME_TYPE_DATA_WITH_ACK", err) } } @@ -571,8 +560,7 @@ func (b *Bebop) packetReceiver(buf []byte) { arstreamFrame := NewARStreamFrame(frame.Data) ack := b.createARStreamACK(arstreamFrame).Bytes() - _, err := b.write(ack) - if err != nil { + if err := b.write(ack); err != nil { fmt.Println("ARNETWORKAL_FRAME_TYPE_DATA_LOW_LATENCY", err) } } @@ -582,8 +570,7 @@ func (b *Bebop) packetReceiver(buf []byte) { // if frame.Id == int(ARNETWORK_MANAGER_INTERNAL_BUFFER_ID_PING) { pong := b.createPong(frame).Bytes() - _, err := b.write(pong) - if err != nil { + if err := b.write(pong); err != nil { fmt.Println("ARNETWORK_MANAGER_INTERNAL_BUFFER_ID_PING", err) } } @@ -592,15 +579,13 @@ func (b *Bebop) packetReceiver(buf []byte) { func (b *Bebop) StartRecording() error { buf := b.videoRecord(ARCOMMANDS_ARDRONE3_MEDIARECORD_VIDEO_RECORD_START) - _, err := b.write(b.networkFrameGenerator(buf, ARNETWORKAL_FRAME_TYPE_DATA, BD_NET_CD_NONACK_ID).Bytes()) - return err + return b.write(b.networkFrameGenerator(buf, ARNETWORKAL_FRAME_TYPE_DATA, BD_NET_CD_NONACK_ID).Bytes()) } func (b *Bebop) StopRecording() error { buf := b.videoRecord(ARCOMMANDS_ARDRONE3_MEDIARECORD_VIDEO_RECORD_STOP) - _, err := b.write(b.networkFrameGenerator(buf, ARNETWORKAL_FRAME_TYPE_DATA, BD_NET_CD_NONACK_ID).Bytes()) - return err + return b.write(b.networkFrameGenerator(buf, ARNETWORKAL_FRAME_TYPE_DATA, BD_NET_CD_NONACK_ID).Bytes()) } func (b *Bebop) videoRecord(state byte) *bytes.Buffer { @@ -665,8 +650,7 @@ func (b *Bebop) HullProtection(protect bool) error { } cmd.Write(tmp.Bytes()) - _, err := b.write(b.networkFrameGenerator(cmd, ARNETWORKAL_FRAME_TYPE_DATA, BD_NET_CD_NONACK_ID).Bytes()) - return err + return b.write(b.networkFrameGenerator(cmd, ARNETWORKAL_FRAME_TYPE_DATA, BD_NET_CD_NONACK_ID).Bytes()) } func (b *Bebop) Outdoor(outdoor bool) error { @@ -695,8 +679,7 @@ func (b *Bebop) Outdoor(outdoor bool) error { } cmd.Write(tmp.Bytes()) - _, err := b.write(b.networkFrameGenerator(cmd, ARNETWORKAL_FRAME_TYPE_DATA, BD_NET_CD_NONACK_ID).Bytes()) - return err + return b.write(b.networkFrameGenerator(cmd, ARNETWORKAL_FRAME_TYPE_DATA, BD_NET_CD_NONACK_ID).Bytes()) } func (b *Bebop) VideoEnable(enable bool) error { @@ -721,8 +704,7 @@ func (b *Bebop) VideoEnable(enable bool) error { } cmd.Write(tmp.Bytes()) - _, err := b.write(b.networkFrameGenerator(cmd, ARNETWORKAL_FRAME_TYPE_DATA, BD_NET_CD_NONACK_ID).Bytes()) - return err + return b.write(b.networkFrameGenerator(cmd, ARNETWORKAL_FRAME_TYPE_DATA, BD_NET_CD_NONACK_ID).Bytes()) } func (b *Bebop) VideoStreamMode(mode int8) error { @@ -747,8 +729,7 @@ func (b *Bebop) VideoStreamMode(mode int8) error { } cmd.Write(tmp.Bytes()) - _, err := b.write(b.networkFrameGenerator(cmd, ARNETWORKAL_FRAME_TYPE_DATA, BD_NET_CD_NONACK_ID).Bytes()) - return err + return b.write(b.networkFrameGenerator(cmd, ARNETWORKAL_FRAME_TYPE_DATA, BD_NET_CD_NONACK_ID).Bytes()) } func bool2int8(b bool) int8 { @@ -834,13 +815,13 @@ func (b *Bebop) createARStreamACK(frame ARStreamFrame) *bytes.Buffer { ackPacket.Write(tmp.Bytes()) tmp = &bytes.Buffer{} - if err := binary.Write(tmp, binary.LittleEndian, uint64(b.tmpFrame.arstreamACK.HighPacketsAck)); err != nil { + if err := binary.Write(tmp, binary.LittleEndian, b.tmpFrame.arstreamACK.HighPacketsAck); err != nil { panic(err) } ackPacket.Write(tmp.Bytes()) tmp = &bytes.Buffer{} - if err := binary.Write(tmp, binary.LittleEndian, uint64(b.tmpFrame.arstreamACK.LowPacketsAck)); err != nil { + if err := binary.Write(tmp, binary.LittleEndian, b.tmpFrame.arstreamACK.LowPacketsAck); err != nil { panic(err) } ackPacket.Write(tmp.Bytes()) diff --git a/platforms/parrot/bebop/client/examples/video.go b/platforms/parrot/bebop/client/examples/video.go index 3946c42c2..0e3731f7d 100644 --- a/platforms/parrot/bebop/client/examples/video.go +++ b/platforms/parrot/bebop/client/examples/video.go @@ -53,14 +53,12 @@ func main() { ffmpeg := exec.Command("ffmpeg", "-i", "pipe:0", "http://localhost:8090/bebop.ffm") ffmpegErr, err := ffmpeg.StderrPipe() - if err != nil { fmt.Println(err) return } ffmpegIn, err := ffmpeg.StdinPipe() - if err != nil { fmt.Println(err) return diff --git a/platforms/parrot/bebop/pitch_test.go b/platforms/parrot/bebop/pitch_test.go index 62dc13980..bf119f347 100644 --- a/platforms/parrot/bebop/pitch_test.go +++ b/platforms/parrot/bebop/pitch_test.go @@ -3,17 +3,17 @@ package bebop import ( "testing" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) func TestBebopValidatePitchWhenEqualOffset(t *testing.T) { - gobottest.Assert(t, ValidatePitch(32767.0, 32767.0), 100) + assert.Equal(t, 100, ValidatePitch(32767.0, 32767.0)) } func TestBebopValidatePitchWhenTiny(t *testing.T) { - gobottest.Assert(t, ValidatePitch(1.1, 32767.0), 0) + assert.Equal(t, 0, ValidatePitch(1.1, 32767.0)) } func TestBebopValidatePitchWhenCentered(t *testing.T) { - gobottest.Assert(t, ValidatePitch(16383.5, 32767.0), 50) + assert.Equal(t, 50, ValidatePitch(16383.5, 32767.0)) } diff --git a/platforms/parrot/minidrone/minidrone_driver.go b/platforms/parrot/minidrone/minidrone_driver.go index e1d3a1183..926ea0bdb 100644 --- a/platforms/parrot/minidrone/minidrone_driver.go +++ b/platforms/parrot/minidrone/minidrone_driver.go @@ -25,8 +25,8 @@ type Driver struct { const ( // BLE services - //droneCommandService = "9a66fa000800919111e4012d1540cb8e" - //droneNotificationService = "9a66fb000800919111e4012d1540cb8e" + // droneCommandService = "9a66fa000800919111e4012d1540cb8e" + // droneNotificationService = "9a66fb000800919111e4012d1540cb8e" // send characteristics pcmdCharacteristic = "9a66fa0a0800919111e4012d1540cb8e" @@ -419,7 +419,6 @@ func (b *Driver) GunControl(id uint8) error { b.stepsfa0b++ buf := []byte{0x02, byte(b.stepsfa0b) & 0xff, 0x02, 0x10, 0x02, id, 0x00} return b.adaptor().WriteCharacteristic(commandCharacteristic, buf) - } func (b *Driver) generateAnimation(direction int8) *bytes.Buffer { @@ -468,7 +467,7 @@ func (b *Driver) generatePcmd() *bytes.Buffer { if err := binary.Write(cmd, binary.LittleEndian, int8(pcmd.Gaz)); err != nil { panic(err) } - if err := binary.Write(cmd, binary.LittleEndian, float32(pcmd.Psi)); err != nil { + if err := binary.Write(cmd, binary.LittleEndian, pcmd.Psi); err != nil { panic(err) } if err := binary.Write(cmd, binary.LittleEndian, int16(0)); err != nil { diff --git a/platforms/parrot/minidrone/minidrone_driver_test.go b/platforms/parrot/minidrone/minidrone_driver_test.go index d57a65ae2..a197a8947 100644 --- a/platforms/parrot/minidrone/minidrone_driver_test.go +++ b/platforms/parrot/minidrone/minidrone_driver_test.go @@ -4,8 +4,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*Driver)(nil) @@ -17,154 +17,154 @@ func initTestMinidroneDriver() *Driver { func TestMinidroneDriver(t *testing.T) { d := initTestMinidroneDriver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "Minidrone"), true) + assert.True(t, strings.HasPrefix(d.Name(), "Minidrone")) d.SetName("NewName") - gobottest.Assert(t, d.Name(), "NewName") + assert.Equal(t, "NewName", d.Name()) } func TestMinidroneDriverStartAndHalt(t *testing.T) { d := initTestMinidroneDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Halt()) } func TestMinidroneTakeoff(t *testing.T) { d := initTestMinidroneDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.TakeOff(), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.TakeOff()) } func TestMinidroneEmergency(t *testing.T) { d := initTestMinidroneDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Emergency(), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Emergency()) } func TestMinidroneTakePicture(t *testing.T) { d := initTestMinidroneDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.TakePicture(), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.TakePicture()) } func TestMinidroneUp(t *testing.T) { d := initTestMinidroneDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Up(25), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Up(25)) } func TestMinidroneUpTooFar(t *testing.T) { d := initTestMinidroneDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Up(125), nil) - gobottest.Assert(t, d.Up(-50), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Up(125)) + assert.NoError(t, d.Up(-50)) } func TestMinidroneDown(t *testing.T) { d := initTestMinidroneDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Down(25), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Down(25)) } func TestMinidroneForward(t *testing.T) { d := initTestMinidroneDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Forward(25), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Forward(25)) } func TestMinidroneBackward(t *testing.T) { d := initTestMinidroneDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Backward(25), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Backward(25)) } func TestMinidroneRight(t *testing.T) { d := initTestMinidroneDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Right(25), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Right(25)) } func TestMinidroneLeft(t *testing.T) { d := initTestMinidroneDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Left(25), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Left(25)) } func TestMinidroneClockwise(t *testing.T) { d := initTestMinidroneDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Clockwise(25), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Clockwise(25)) } func TestMinidroneCounterClockwise(t *testing.T) { d := initTestMinidroneDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.CounterClockwise(25), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.CounterClockwise(25)) } func TestMinidroneStop(t *testing.T) { d := initTestMinidroneDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Stop(), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Stop()) } func TestMinidroneStartStopRecording(t *testing.T) { d := initTestMinidroneDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.StartRecording(), nil) - gobottest.Assert(t, d.StopRecording(), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.StartRecording()) + assert.NoError(t, d.StopRecording()) } func TestMinidroneHullProtectionOutdoor(t *testing.T) { d := initTestMinidroneDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.HullProtection(true), nil) - gobottest.Assert(t, d.Outdoor(true), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.HullProtection(true)) + assert.NoError(t, d.Outdoor(true)) } func TestMinidroneHullFlips(t *testing.T) { d := initTestMinidroneDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.FrontFlip(), nil) - gobottest.Assert(t, d.BackFlip(), nil) - gobottest.Assert(t, d.RightFlip(), nil) - gobottest.Assert(t, d.LeftFlip(), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.FrontFlip()) + assert.NoError(t, d.BackFlip()) + assert.NoError(t, d.RightFlip()) + assert.NoError(t, d.LeftFlip()) } func TestMinidroneLightControl(t *testing.T) { d := initTestMinidroneDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.LightControl(0, LightBlinked, 25), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.LightControl(0, LightBlinked, 25)) } func TestMinidroneClawControl(t *testing.T) { d := initTestMinidroneDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.ClawControl(0, ClawOpen), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.ClawControl(0, ClawOpen)) } func TestMinidroneGunControl(t *testing.T) { d := initTestMinidroneDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.GunControl(0), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.GunControl(0)) } func TestMinidroneProcessFlightData(t *testing.T) { d := initTestMinidroneDriver() - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) d.processFlightStatus([]byte{0x00, 0x00, 0x00}) d.processFlightStatus([]byte{0x00, 0x00, 0x00, 0x00, 0x00}) d.processFlightStatus([]byte{0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}) - gobottest.Assert(t, d.flying, false) + assert.False(t, d.flying) d.processFlightStatus([]byte{0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01}) - gobottest.Assert(t, d.flying, false) + assert.False(t, d.flying) d.processFlightStatus([]byte{0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02}) - gobottest.Assert(t, d.flying, true) + assert.True(t, d.flying) d.processFlightStatus([]byte{0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03}) - gobottest.Assert(t, d.flying, true) + assert.True(t, d.flying) d.processFlightStatus([]byte{0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04}) d.processFlightStatus([]byte{0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05}) d.processFlightStatus([]byte{0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06}) - gobottest.Assert(t, d.Stop(), nil) + assert.NoError(t, d.Stop()) } diff --git a/platforms/parrot/minidrone/pitch_test.go b/platforms/parrot/minidrone/pitch_test.go index 8b0261715..51b838bed 100644 --- a/platforms/parrot/minidrone/pitch_test.go +++ b/platforms/parrot/minidrone/pitch_test.go @@ -3,17 +3,17 @@ package minidrone import ( "testing" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) func TestMinidroneValidatePitchWhenEqualOffset(t *testing.T) { - gobottest.Assert(t, ValidatePitch(32767.0, 32767.0), 100) + assert.Equal(t, 100, ValidatePitch(32767.0, 32767.0)) } func TestMinidroneValidatePitchWhenTiny(t *testing.T) { - gobottest.Assert(t, ValidatePitch(1.1, 32767.0), 0) + assert.Equal(t, 0, ValidatePitch(1.1, 32767.0)) } func TestMinidroneValidatePitchWhenCentered(t *testing.T) { - gobottest.Assert(t, ValidatePitch(16383.5, 32767.0), 50) + assert.Equal(t, 50, ValidatePitch(16383.5, 32767.0)) } diff --git a/platforms/particle/adaptor.go b/platforms/particle/adaptor.go index dbaaf0ca9..2d6b3262f 100644 --- a/platforms/particle/adaptor.go +++ b/platforms/particle/adaptor.go @@ -182,7 +182,6 @@ func (s *Adaptor) EventStream(source string, name string) (event *gobot.Event, e func (s *Adaptor) Variable(name string) (result string, err error) { url := fmt.Sprintf("%v/%s?access_token=%s", s.deviceURL(), name, s.AccessToken) resp, err := s.request("GET", url, nil) - if err != nil { return } @@ -245,9 +244,9 @@ func (s *Adaptor) request(method string, url string, params url.Values) (m map[s var resp *http.Response if method == "POST" { - resp, err = http.PostForm(url, params) + resp, err = http.PostForm(url, params) //nolint:gosec // accepted, because local function and no exposed routing } else if method == "GET" { - resp, err = http.Get(url) + resp, err = http.Get(url) //nolint:gosec // accepted, because local function and no exposed routing } if err != nil { @@ -255,7 +254,6 @@ func (s *Adaptor) request(method string, url string, params url.Values) (m map[s } buf, err := io.ReadAll(resp.Body) - if err != nil { return } diff --git a/platforms/particle/adaptor_test.go b/platforms/particle/adaptor_test.go index 0c55db12e..544804e76 100644 --- a/platforms/particle/adaptor_test.go +++ b/platforms/particle/adaptor_test.go @@ -9,8 +9,8 @@ import ( "testing" "github.com/donovanhide/eventsource" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) // HELPERS @@ -79,22 +79,22 @@ func TestNewAdaptor(t *testing.T) { t.Errorf("NewAdaptor() should have returned a *Adaptor") } - gobottest.Assert(t, core.APIServer, "https://api.particle.io") - gobottest.Assert(t, strings.HasPrefix(core.Name(), "Particle"), true) + assert.Equal(t, "https://api.particle.io", core.APIServer) + assert.True(t, strings.HasPrefix(core.Name(), "Particle")) core.SetName("sparkie") - gobottest.Assert(t, core.Name(), "sparkie") + assert.Equal(t, "sparkie", core.Name()) } func TestAdaptorConnect(t *testing.T) { a := initTestAdaptor() - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) } func TestAdaptorFinalize(t *testing.T) { a := initTestAdaptor() _ = a.Connect() - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) } func TestAdaptorAnalogRead(t *testing.T) { @@ -109,7 +109,7 @@ func TestAdaptorAnalogRead(t *testing.T) { defer testServer.Close() val, _ := a.AnalogRead("A1") - gobottest.Assert(t, val, 5) + assert.Equal(t, 5, val) } func TestAdaptorAnalogReadError(t *testing.T) { @@ -122,7 +122,7 @@ func TestAdaptorAnalogReadError(t *testing.T) { a.setAPIServer(testServer.URL) val, _ := a.AnalogRead("A1") - gobottest.Assert(t, val, 0) + assert.Equal(t, 0, val) } func TestAdaptorPwmWrite(t *testing.T) { @@ -206,7 +206,7 @@ func TestAdaptorDigitalRead(t *testing.T) { a.setAPIServer(testServer.URL) val, _ := a.DigitalRead("D7") - gobottest.Assert(t, val, 1) + assert.Equal(t, 1, val) testServer.Close() // When LOW @@ -218,7 +218,7 @@ func TestAdaptorDigitalRead(t *testing.T) { defer testServer.Close() val, _ = a.DigitalRead("D7") - gobottest.Assert(t, val, 0) + assert.Equal(t, 0, val) } func TestAdaptorDigitalReadError(t *testing.T) { @@ -232,7 +232,7 @@ func TestAdaptorDigitalReadError(t *testing.T) { a.setAPIServer(testServer.URL) val, _ := a.DigitalRead("D7") - gobottest.Assert(t, val, -1) + assert.Equal(t, -1, val) } func TestAdaptorFunction(t *testing.T) { @@ -244,7 +244,7 @@ func TestAdaptorFunction(t *testing.T) { a.setAPIServer(testServer.URL) val, _ := a.Function("hello", "100,200") - gobottest.Assert(t, val, 1) + assert.Equal(t, 1, val) testServer.Close() // When not existent @@ -254,7 +254,7 @@ func TestAdaptorFunction(t *testing.T) { a.setAPIServer(testServer.URL) _, err := a.Function("hello", "") - gobottest.Assert(t, err.Error(), "timeout") + assert.ErrorContains(t, err, "timeout") testServer.Close() } @@ -269,7 +269,7 @@ func TestAdaptorVariable(t *testing.T) { a.setAPIServer(testServer.URL) val, _ := a.Variable("variable_name") - gobottest.Assert(t, val, "1") + assert.Equal(t, "1", val) testServer.Close() // When float @@ -279,7 +279,7 @@ func TestAdaptorVariable(t *testing.T) { a.setAPIServer(testServer.URL) val, _ = a.Variable("variable_name") - gobottest.Assert(t, val, "1.1") + assert.Equal(t, "1.1", val) testServer.Close() // When int @@ -289,7 +289,7 @@ func TestAdaptorVariable(t *testing.T) { a.setAPIServer(testServer.URL) val, _ = a.Variable("variable_name") - gobottest.Assert(t, val, "1") + assert.Equal(t, "1", val) testServer.Close() // When bool @@ -299,7 +299,7 @@ func TestAdaptorVariable(t *testing.T) { a.setAPIServer(testServer.URL) val, _ = a.Variable("variable_name") - gobottest.Assert(t, val, "true") + assert.Equal(t, "true", val) testServer.Close() // When not existent @@ -309,7 +309,7 @@ func TestAdaptorVariable(t *testing.T) { a.setAPIServer(testServer.URL) _, err := a.Variable("not_existent") - gobottest.Assert(t, err.Error(), "Variable not found") + assert.ErrorContains(t, err, "Variable not found") testServer.Close() } @@ -317,10 +317,10 @@ func TestAdaptorVariable(t *testing.T) { func TestAdaptorSetAPIServer(t *testing.T) { a := initTestAdaptor() apiServer := "new_api_server" - gobottest.Refute(t, a.APIServer, apiServer) + assert.NotEqual(t, apiServer, a.APIServer) a.setAPIServer(apiServer) - gobottest.Assert(t, a.APIServer, apiServer) + assert.Equal(t, apiServer, a.APIServer) } func TestAdaptorDeviceURL(t *testing.T) { @@ -328,19 +328,19 @@ func TestAdaptorDeviceURL(t *testing.T) { a := initTestAdaptor() a.setAPIServer("http://server") a.DeviceID = "devID" - gobottest.Assert(t, a.deviceURL(), "http://server/v1/devices/devID") + assert.Equal(t, "http://server/v1/devices/devID", a.deviceURL()) // When APIServer is not set a = &Adaptor{name: "particleie", DeviceID: "myDevice", AccessToken: "token"} - gobottest.Assert(t, a.deviceURL(), "https://api.particle.io/v1/devices/myDevice") + assert.Equal(t, "https://api.particle.io/v1/devices/myDevice", a.deviceURL()) } func TestAdaptorPinLevel(t *testing.T) { a := initTestAdaptor() - gobottest.Assert(t, a.pinLevel(1), "HIGH") - gobottest.Assert(t, a.pinLevel(0), "LOW") - gobottest.Assert(t, a.pinLevel(5), "LOW") + assert.Equal(t, "HIGH", a.pinLevel(1)) + assert.Equal(t, "LOW", a.pinLevel(0)) + assert.Equal(t, "LOW", a.pinLevel(5)) } func TestAdaptorPostToparticle(t *testing.T) { @@ -377,23 +377,23 @@ func TestAdaptorEventStream(t *testing.T) { return nil, nil, nil } _, _ = a.EventStream("all", "ping") - gobottest.Assert(t, url, "https://api.particle.io/v1/events/ping?access_token=token") + assert.Equal(t, "https://api.particle.io/v1/events/ping?access_token=token", url) _, _ = a.EventStream("devices", "ping") - gobottest.Assert(t, url, "https://api.particle.io/v1/devices/events/ping?access_token=token") + assert.Equal(t, "https://api.particle.io/v1/devices/events/ping?access_token=token", url) _, _ = a.EventStream("device", "ping") - gobottest.Assert(t, url, "https://api.particle.io/v1/devices/myDevice/events/ping?access_token=token") + assert.Equal(t, "https://api.particle.io/v1/devices/myDevice/events/ping?access_token=token", url) _, err := a.EventStream("nothing", "ping") - gobottest.Assert(t, err.Error(), "source param should be: all, devices or device") + assert.ErrorContains(t, err, "source param should be: all, devices or device") eventSource = func(u string) (chan eventsource.Event, chan error, error) { return nil, nil, errors.New("error connecting sse") } _, err = a.EventStream("devices", "") - gobottest.Assert(t, err.Error(), "error connecting sse") + assert.ErrorContains(t, err, "error connecting sse") eventChan := make(chan eventsource.Event) errorChan := make(chan error) @@ -403,5 +403,5 @@ func TestAdaptorEventStream(t *testing.T) { } _, err = a.EventStream("devices", "") - gobottest.Assert(t, err, nil) + assert.NoError(t, err) } diff --git a/platforms/pebble/pebble_adaptor_test.go b/platforms/pebble/pebble_adaptor_test.go index 2ae333ab6..b7b4577ac 100644 --- a/platforms/pebble/pebble_adaptor_test.go +++ b/platforms/pebble/pebble_adaptor_test.go @@ -3,8 +3,8 @@ package pebble import ( "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Adaptor = (*Adaptor)(nil) @@ -15,14 +15,15 @@ func initTestAdaptor() *Adaptor { func TestAdaptor(t *testing.T) { a := initTestAdaptor() - gobottest.Assert(t, a.Name(), "Pebble") + assert.Equal(t, "Pebble", a.Name()) } + func TestAdaptorConnect(t *testing.T) { a := initTestAdaptor() - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) } func TestAdaptorFinalize(t *testing.T) { a := initTestAdaptor() - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) } diff --git a/platforms/pebble/pebble_driver_test.go b/platforms/pebble/pebble_driver_test.go index cbf0cd695..b68f3f3f8 100644 --- a/platforms/pebble/pebble_driver_test.go +++ b/platforms/pebble/pebble_driver_test.go @@ -4,8 +4,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*Driver)(nil) @@ -16,28 +16,28 @@ func initTestDriver() *Driver { func TestDriverStart(t *testing.T) { d := initTestDriver() - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestDriverHalt(t *testing.T) { d := initTestDriver() - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestDriver(t *testing.T) { d := initTestDriver() - gobottest.Assert(t, d.Name(), "Pebble") - gobottest.Assert(t, d.Connection().Name(), "Pebble") + assert.Equal(t, "Pebble", d.Name()) + assert.Equal(t, "Pebble", d.Connection().Name()) sem := make(chan bool) d.SendNotification("Hello") d.SendNotification("World") - gobottest.Assert(t, d.Messages[0], "Hello") - gobottest.Assert(t, d.PendingMessage(), "Hello") - gobottest.Assert(t, d.PendingMessage(), "World") - gobottest.Assert(t, d.PendingMessage(), "") + assert.Equal(t, "Hello", d.Messages[0]) + assert.Equal(t, "Hello", d.PendingMessage()) + assert.Equal(t, "World", d.PendingMessage()) + assert.Equal(t, "", d.PendingMessage()) _ = d.On(d.Event("button"), func(data interface{}) { sem <- true @@ -64,8 +64,8 @@ func TestDriver(t *testing.T) { } d.Command("send_notification")(map[string]interface{}{"message": "Hey buddy!"}) - gobottest.Assert(t, d.Messages[0], "Hey buddy!") + assert.Equal(t, "Hey buddy!", d.Messages[0]) message := d.Command("pending_message")(map[string]interface{}{}) - gobottest.Assert(t, message, "Hey buddy!") + assert.Equal(t, "Hey buddy!", message) } diff --git a/platforms/raspi/pwm_pin.go b/platforms/raspi/pwm_pin.go index 366ca698d..05f49a952 100644 --- a/platforms/raspi/pwm_pin.go +++ b/platforms/raspi/pwm_pin.go @@ -107,7 +107,7 @@ func (p *PWMPin) SetDutyCycle(duty uint32) error { } func (p *PWMPin) writeValue(data string) (err error) { - fi, err := p.sys.OpenFile(p.path, os.O_WRONLY|os.O_APPEND, 0644) + fi, err := p.sys.OpenFile(p.path, os.O_WRONLY|os.O_APPEND, 0o644) defer fi.Close() //nolint:staticcheck // for historical reasons if err != nil { diff --git a/platforms/raspi/pwm_pin_test.go b/platforms/raspi/pwm_pin_test.go index df0cc2f6c..ea3cc6f82 100644 --- a/platforms/raspi/pwm_pin_test.go +++ b/platforms/raspi/pwm_pin_test.go @@ -1,11 +1,10 @@ package raspi import ( - "errors" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" "gobot.io/x/gobot/v2/system" ) @@ -18,37 +17,37 @@ func TestPwmPin(t *testing.T) { pin := NewPWMPin(a, path, "1") - gobottest.Assert(t, pin.Export(), nil) - gobottest.Assert(t, pin.SetEnabled(true), nil) + assert.NoError(t, pin.Export()) + assert.NoError(t, pin.SetEnabled(true)) val, _ := pin.Polarity() - gobottest.Assert(t, val, true) + assert.True(t, val) - gobottest.Assert(t, pin.SetPolarity(false), nil) + assert.NoError(t, pin.SetPolarity(false)) val, _ = pin.Polarity() - gobottest.Assert(t, val, true) + assert.True(t, val) _, err := pin.Period() - gobottest.Assert(t, err, errors.New("Raspi PWM pin period not set")) - gobottest.Assert(t, pin.SetDutyCycle(10000), errors.New("Raspi PWM pin period not set")) + assert.ErrorContains(t, err, "Raspi PWM pin period not set") + assert.ErrorContains(t, pin.SetDutyCycle(10000), "Raspi PWM pin period not set") - gobottest.Assert(t, pin.SetPeriod(20000000), nil) + assert.NoError(t, pin.SetPeriod(20000000)) period, _ := pin.Period() - gobottest.Assert(t, period, uint32(20000000)) - gobottest.Assert(t, pin.SetPeriod(10000000), errors.New("Cannot set the period of individual PWM pins on Raspi")) + assert.Equal(t, uint32(20000000), period) + assert.ErrorContains(t, pin.SetPeriod(10000000), "Cannot set the period of individual PWM pins on Raspi") dc, _ := pin.DutyCycle() - gobottest.Assert(t, dc, uint32(0)) + assert.Equal(t, uint32(0), dc) - gobottest.Assert(t, pin.SetDutyCycle(10000), nil) + assert.NoError(t, pin.SetDutyCycle(10000)) dc, _ = pin.DutyCycle() - gobottest.Assert(t, dc, uint32(10000)) + assert.Equal(t, uint32(10000), dc) - gobottest.Assert(t, pin.SetDutyCycle(999999999), errors.New("Duty cycle exceeds period")) + assert.ErrorContains(t, pin.SetDutyCycle(999999999), "Duty cycle exceeds period") dc, _ = pin.DutyCycle() - gobottest.Assert(t, dc, uint32(10000)) + assert.Equal(t, uint32(10000), dc) - gobottest.Assert(t, pin.Unexport(), nil) + assert.NoError(t, pin.Unexport()) } diff --git a/platforms/raspi/raspi_adaptor.go b/platforms/raspi/raspi_adaptor.go index 19414926a..2d915d550 100644 --- a/platforms/raspi/raspi_adaptor.go +++ b/platforms/raspi/raspi_adaptor.go @@ -5,7 +5,6 @@ import ( "fmt" "strconv" "strings" - "sync" multierror "github.com/hashicorp/go-multierror" @@ -209,7 +208,7 @@ func (c *Adaptor) readRevision() string { } for _, v := range strings.Split(string(content), "\n") { if strings.Contains(v, "Revision") { - s := strings.Split(string(v), " ") + s := strings.Split(v, " ") version, _ := strconv.ParseInt("0x"+s[len(s)-1], 0, 64) if version <= 3 { c.revision = "1" diff --git a/platforms/raspi/raspi_adaptor_test.go b/platforms/raspi/raspi_adaptor_test.go index 560fed662..402916421 100644 --- a/platforms/raspi/raspi_adaptor_test.go +++ b/platforms/raspi/raspi_adaptor_test.go @@ -1,33 +1,33 @@ package raspi import ( - "errors" "fmt" - "strings" - "testing" - "runtime" "strconv" + "strings" "sync" + "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" "gobot.io/x/gobot/v2/drivers/gpio" "gobot.io/x/gobot/v2/drivers/i2c" "gobot.io/x/gobot/v2/drivers/spi" - "gobot.io/x/gobot/v2/gobottest" "gobot.io/x/gobot/v2/system" ) // make sure that this Adaptor fulfills all the required interfaces -var _ gobot.Adaptor = (*Adaptor)(nil) -var _ gobot.DigitalPinnerProvider = (*Adaptor)(nil) -var _ gobot.PWMPinnerProvider = (*Adaptor)(nil) -var _ gpio.DigitalReader = (*Adaptor)(nil) -var _ gpio.DigitalWriter = (*Adaptor)(nil) -var _ gpio.PwmWriter = (*Adaptor)(nil) -var _ gpio.ServoWriter = (*Adaptor)(nil) -var _ i2c.Connector = (*Adaptor)(nil) -var _ spi.Connector = (*Adaptor)(nil) +var ( + _ gobot.Adaptor = (*Adaptor)(nil) + _ gobot.DigitalPinnerProvider = (*Adaptor)(nil) + _ gobot.PWMPinnerProvider = (*Adaptor)(nil) + _ gpio.DigitalReader = (*Adaptor)(nil) + _ gpio.DigitalWriter = (*Adaptor)(nil) + _ gpio.PwmWriter = (*Adaptor)(nil) + _ gpio.ServoWriter = (*Adaptor)(nil) + _ i2c.Connector = (*Adaptor)(nil) + _ spi.Connector = (*Adaptor)(nil) +) func initTestAdaptorWithMockedFilesystem(mockPaths []string) (*Adaptor, *system.MockFilesystem) { a := NewAdaptor() @@ -39,14 +39,14 @@ func initTestAdaptorWithMockedFilesystem(mockPaths []string) (*Adaptor, *system. func TestName(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, strings.HasPrefix(a.Name(), "RaspberryPi"), true) + assert.True(t, strings.HasPrefix(a.Name(), "RaspberryPi")) a.SetName("NewName") - gobottest.Assert(t, a.Name(), "NewName") + assert.Equal(t, "NewName", a.Name()) } func TestGetDefaultBus(t *testing.T) { const contentPattern = "Hardware : BCM2708\n%sSerial : 000000003bc748ea\n" - var tests = map[string]struct { + tests := map[string]struct { revisionPart string wantRev string wantBus int @@ -77,12 +77,12 @@ func TestGetDefaultBus(t *testing.T) { a := NewAdaptor() fs := a.sys.UseMockFilesystem([]string{infoFile}) fs.Files[infoFile].Contents = fmt.Sprintf(contentPattern, tc.revisionPart) - gobottest.Assert(t, a.revision, "") - //act, will read and refresh the revision + assert.Equal(t, "", a.revision) + // act, will read and refresh the revision gotBus := a.DefaultI2cBus() - //assert - gobottest.Assert(t, a.revision, tc.wantRev) - gobottest.Assert(t, gotBus, tc.wantBus) + // assert + assert.Equal(t, tc.wantRev, a.revision) + assert.Equal(t, tc.wantBus, gotBus) }) } } @@ -103,7 +103,7 @@ func TestFinalize(t *testing.T) { _ = a.PwmWrite("7", 255) _, _ = a.GetI2cConnection(0xff, 0) - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) } func TestDigitalPWM(t *testing.T) { @@ -111,30 +111,30 @@ func TestDigitalPWM(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem(mockedPaths) a.PiBlasterPeriod = 20000000 - gobottest.Assert(t, a.PwmWrite("7", 4), nil) + assert.NoError(t, a.PwmWrite("7", 4)) pin, _ := a.PWMPin("7") period, _ := pin.Period() - gobottest.Assert(t, period, uint32(20000000)) + assert.Equal(t, uint32(20000000), period) - gobottest.Assert(t, a.PwmWrite("7", 255), nil) + assert.NoError(t, a.PwmWrite("7", 255)) - gobottest.Assert(t, strings.Split(fs.Files["/dev/pi-blaster"].Contents, "\n")[0], "4=1") + assert.Equal(t, "4=1", strings.Split(fs.Files["/dev/pi-blaster"].Contents, "\n")[0]) - gobottest.Assert(t, a.ServoWrite("11", 90), nil) + assert.NoError(t, a.ServoWrite("11", 90)) - gobottest.Assert(t, strings.Split(fs.Files["/dev/pi-blaster"].Contents, "\n")[0], "17=0.5") + assert.Equal(t, "17=0.5", strings.Split(fs.Files["/dev/pi-blaster"].Contents, "\n")[0]) - gobottest.Assert(t, a.PwmWrite("notexist", 1), errors.New("Not a valid pin")) - gobottest.Assert(t, a.ServoWrite("notexist", 1), errors.New("Not a valid pin")) + assert.ErrorContains(t, a.PwmWrite("notexist", 1), "Not a valid pin") + assert.ErrorContains(t, a.ServoWrite("notexist", 1), "Not a valid pin") pin, _ = a.PWMPin("12") period, _ = pin.Period() - gobottest.Assert(t, period, uint32(20000000)) + assert.Equal(t, uint32(20000000), period) - gobottest.Assert(t, pin.SetDutyCycle(1.5*1000*1000), nil) + assert.NoError(t, pin.SetDutyCycle(1.5*1000*1000)) - gobottest.Assert(t, strings.Split(fs.Files["/dev/pi-blaster"].Contents, "\n")[0], "18=0.075") + assert.Equal(t, "18=0.075", strings.Split(fs.Files["/dev/pi-blaster"].Contents, "\n")[0]) } func TestDigitalIO(t *testing.T) { @@ -149,19 +149,19 @@ func TestDigitalIO(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem(mockedPaths) err := a.DigitalWrite("7", 1) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files["/sys/class/gpio/gpio4/value"].Contents, "1") + assert.NoError(t, err) + assert.Equal(t, "1", fs.Files["/sys/class/gpio/gpio4/value"].Contents) a.revision = "2" err = a.DigitalWrite("13", 1) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) i, err := a.DigitalRead("13") - gobottest.Assert(t, err, nil) - gobottest.Assert(t, i, 1) + assert.NoError(t, err) + assert.Equal(t, 1, i) - gobottest.Assert(t, a.DigitalWrite("notexist", 1), errors.New("Not a valid pin")) - gobottest.Assert(t, a.Finalize(), nil) + assert.ErrorContains(t, a.DigitalWrite("notexist", 1), "Not a valid pin") + assert.NoError(t, a.Finalize()) } func TestDigitalPinConcurrency(t *testing.T) { @@ -193,24 +193,24 @@ func TestPWMPin(t *testing.T) { panic(err) } - gobottest.Assert(t, len(a.pwmPins), 0) + assert.Equal(t, 0, len(a.pwmPins)) a.revision = "3" firstSysPin, err := a.PWMPin("35") - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.pwmPins), 1) + assert.NoError(t, err) + assert.Equal(t, 1, len(a.pwmPins)) secondSysPin, err := a.PWMPin("35") - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.pwmPins), 1) - gobottest.Assert(t, firstSysPin, secondSysPin) + assert.NoError(t, err) + assert.Equal(t, 1, len(a.pwmPins)) + assert.Equal(t, secondSysPin, firstSysPin) otherSysPin, err := a.PWMPin("36") - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.pwmPins), 2) - gobottest.Refute(t, firstSysPin, otherSysPin) + assert.NoError(t, err) + assert.Equal(t, 2, len(a.pwmPins)) + assert.NotEqual(t, otherSysPin, firstSysPin) } func TestPWMPinsReConnect(t *testing.T) { @@ -222,27 +222,27 @@ func TestPWMPinsReConnect(t *testing.T) { } _, err := a.PWMPin("35") - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.pwmPins), 1) - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, err) + assert.Equal(t, 1, len(a.pwmPins)) + assert.NoError(t, a.Finalize()) // act err = a.Connect() // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.pwmPins), 0) + assert.NoError(t, err) + assert.Equal(t, 0, len(a.pwmPins)) _, _ = a.PWMPin("35") _, err = a.PWMPin("36") - gobottest.Assert(t, err, nil) - gobottest.Assert(t, len(a.pwmPins), 2) + assert.NoError(t, err) + assert.Equal(t, 2, len(a.pwmPins)) } func TestSpiDefaultValues(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, a.SpiDefaultBusNumber(), 0) - gobottest.Assert(t, a.SpiDefaultChipNumber(), 0) - gobottest.Assert(t, a.SpiDefaultMode(), 0) - gobottest.Assert(t, a.SpiDefaultMaxSpeed(), int64(500000)) + assert.Equal(t, 0, a.SpiDefaultBusNumber()) + assert.Equal(t, 0, a.SpiDefaultChipNumber()) + assert.Equal(t, 0, a.SpiDefaultMode()) + assert.Equal(t, int64(500000), a.SpiDefaultMaxSpeed()) } func TestI2cDefaultBus(t *testing.T) { @@ -251,10 +251,10 @@ func TestI2cDefaultBus(t *testing.T) { a.sys.UseMockSyscall() a.revision = "0" - gobottest.Assert(t, a.DefaultI2cBus(), 0) + assert.Equal(t, 0, a.DefaultI2cBus()) a.revision = "2" - gobottest.Assert(t, a.DefaultI2cBus(), 1) + assert.Equal(t, 1, a.DefaultI2cBus()) } func TestI2cFinalizeWithErrors(t *testing.T) { @@ -262,20 +262,20 @@ func TestI2cFinalizeWithErrors(t *testing.T) { a := NewAdaptor() a.sys.UseMockSyscall() fs := a.sys.UseMockFilesystem([]string{"/dev/i2c-1"}) - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) con, err := a.GetI2cConnection(0xff, 1) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) _, err = con.Write([]byte{0xbf}) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) fs.WithCloseError = true // act err = a.Finalize() // assert - gobottest.Assert(t, strings.Contains(err.Error(), "close error"), true) + assert.Contains(t, err.Error(), "close error") } func Test_validateSpiBusNumber(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { busNr int wantErr error }{ @@ -301,13 +301,13 @@ func Test_validateSpiBusNumber(t *testing.T) { // act err := a.validateSpiBusNumber(tc.busNr) // assert - gobottest.Assert(t, err, tc.wantErr) + assert.Equal(t, tc.wantErr, err) }) } } func Test_validateI2cBusNumber(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { busNr int wantErr error }{ @@ -333,7 +333,7 @@ func Test_validateI2cBusNumber(t *testing.T) { // act err := a.validateI2cBusNumber(tc.busNr) // assert - gobottest.Assert(t, err, tc.wantErr) + assert.Equal(t, tc.wantErr, err) }) } } diff --git a/platforms/rockpi/rockpi_adaptor_test.go b/platforms/rockpi/rockpi_adaptor_test.go index 1e3186298..9d1d590e8 100644 --- a/platforms/rockpi/rockpi_adaptor_test.go +++ b/platforms/rockpi/rockpi_adaptor_test.go @@ -4,7 +4,7 @@ import ( "fmt" "testing" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2/system" ) @@ -17,11 +17,11 @@ func initTestAdaptorWithMockedFilesystem(mockPaths []string) (*Adaptor, *system. func TestDefaultI2cBus(t *testing.T) { a, _ := initTestAdaptorWithMockedFilesystem([]string{}) - gobottest.Assert(t, a.DefaultI2cBus(), 7) + assert.Equal(t, 7, a.DefaultI2cBus()) } func Test_getPinTranslatorFunction(t *testing.T) { - var cases = map[string]struct { + cases := map[string]struct { pin string model string expectedLine int @@ -63,15 +63,15 @@ func Test_getPinTranslatorFunction(t *testing.T) { // act chip, line, err := fn(tc.pin) // assert - gobottest.Assert(t, chip, "") - gobottest.Assert(t, err, tc.expectedErr) - gobottest.Assert(t, line, tc.expectedLine) + assert.Equal(t, "", chip) + assert.Equal(t, tc.expectedErr, err) + assert.Equal(t, tc.expectedLine, line) }) } } func Test_validateSpiBusNumber(t *testing.T) { - var cases = map[string]struct { + cases := map[string]struct { busNr int expectedErr error }{ @@ -97,13 +97,13 @@ func Test_validateSpiBusNumber(t *testing.T) { // act err := a.validateSpiBusNumber(tc.busNr) // assert - gobottest.Assert(t, err, tc.expectedErr) + assert.Equal(t, tc.expectedErr, err) }) } } func Test_validateI2cBusNumber(t *testing.T) { - var cases = map[string]struct { + cases := map[string]struct { busNr int wantErr error }{ @@ -132,7 +132,7 @@ func Test_validateI2cBusNumber(t *testing.T) { // act err := a.validateI2cBusNumber(tc.busNr) // assert - gobottest.Assert(t, err, tc.wantErr) + assert.Equal(t, tc.wantErr, err) }) } } diff --git a/platforms/sphero/bb8/bb8_driver_test.go b/platforms/sphero/bb8/bb8_driver_test.go index a56ed5155..d937730f7 100644 --- a/platforms/sphero/bb8/bb8_driver_test.go +++ b/platforms/sphero/bb8/bb8_driver_test.go @@ -4,8 +4,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*BB8Driver)(nil) @@ -17,13 +17,13 @@ func initTestBB8Driver() *BB8Driver { func TestBB8Driver(t *testing.T) { d := initTestBB8Driver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "BB8"), true) + assert.True(t, strings.HasPrefix(d.Name(), "BB8")) d.SetName("NewName") - gobottest.Assert(t, d.Name(), "NewName") + assert.Equal(t, "NewName", d.Name()) } func TestBB8DriverStartAndHalt(t *testing.T) { d := initTestBB8Driver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Halt()) } diff --git a/platforms/sphero/ollie/ollie_driver.go b/platforms/sphero/ollie/ollie_driver.go index eb4f29a18..4ef37d836 100644 --- a/platforms/sphero/ollie/ollie_driver.go +++ b/platforms/sphero/ollie/ollie_driver.go @@ -29,8 +29,8 @@ type Driver struct { const ( // bluetooth service IDs - //spheroBLEService = "22bb746f2bb075542d6f726568705327" - //robotControlService = "22bb746f2ba075542d6f726568705327" + // spheroBLEService = "22bb746f2bb075542d6f726568705327" + // robotControlService = "22bb746f2ba075542d6f726568705327" // BLE characteristic IDs wakeCharacteristic = "22bb746f2bbf75542d6f726568705327" @@ -214,16 +214,15 @@ func (b *Driver) SetTXPower(level int) error { // HandleResponses handles responses returned from Ollie func (b *Driver) HandleResponses(data []byte, e error) { - - //since packets can only be 20 bytes long, we have to puzzle them together + // since packets can only be 20 bytes long, we have to puzzle them together newMessage := false - //append message parts to existing + // append message parts to existing if len(data) > 0 && data[0] != 0xFF { b.asyncBuffer = append(b.asyncBuffer, data...) } - //clear message when new one begins (first byte is always 0xFF) + // clear message when new one begins (first byte is always 0xFF) if len(data) > 0 && data[0] == 0xFF { b.asyncMessage = b.asyncBuffer b.asyncBuffer = data @@ -231,14 +230,14 @@ func (b *Driver) HandleResponses(data []byte, e error) { } parts := b.asyncMessage - //3 is the id of data streaming, located at index 2 byte + // 3 is the id of data streaming, located at index 2 byte if newMessage && len(parts) > 2 && parts[2] == 3 { b.handleDataStreaming(parts) } - //index 1 is the type of the message, 0xFF being a direct response, 0xFE an asynchronous message + // index 1 is the type of the message, 0xFF being a direct response, 0xFE an asynchronous message if len(data) > 4 && data[1] == 0xFF && data[0] == 0xFF { - //locator request + // locator request if data[4] == 0x0B && len(data) == 16 { b.handleLocatorDetected(data) } @@ -253,14 +252,14 @@ func (b *Driver) HandleResponses(data []byte, e error) { // GetLocatorData calls the passed function with the data from the locator func (b *Driver) GetLocatorData(f func(p Point2D)) { - //CID 0x15 is the code for the locator request + // CID 0x15 is the code for the locator request b.PacketChannel() <- b.craftPacket([]uint8{}, 0x02, 0x15) b.locatorCallback = f } // GetPowerState calls the passed function with the Power State information from the sphero func (b *Driver) GetPowerState(f func(p PowerStatePacket)) { - //CID 0x20 is the code for the power state + // CID 0x20 is the code for the power state b.PacketChannel() <- b.craftPacket([]uint8{}, 0x00, 0x20) b.powerstateCallback = f } @@ -271,8 +270,8 @@ func (b *Driver) handleDataStreaming(data []byte) { return } - //data packet is the same as for the normal sphero, since the same communication api is used - //only difference in communication is that the "newer" spheros use BLE for communinations + // data packet is the same as for the normal sphero, since the same communication api is used + // only difference in communication is that the "newer" spheros use BLE for communinations var dataPacket DataStreamingPacket buffer := bytes.NewBuffer(data[5:]) // skip header if err := binary.Read(buffer, binary.BigEndian, &dataPacket); err != nil { @@ -387,7 +386,6 @@ func (b *Driver) craftPacket(body []uint8, did byte, cid byte) *Packet { } func (b *Driver) handlePowerStateDetected(data []uint8) { - var dataPacket PowerStatePacket buffer := bytes.NewBuffer(data[5:]) // skip header if err := binary.Read(buffer, binary.BigEndian, &dataPacket); err != nil { @@ -398,11 +396,11 @@ func (b *Driver) handlePowerStateDetected(data []uint8) { } func (b *Driver) handleLocatorDetected(data []uint8) { - //read the unsigned raw values + // read the unsigned raw values ux := binary.BigEndian.Uint16(data[5:7]) uy := binary.BigEndian.Uint16(data[7:9]) - //convert to signed values + // convert to signed values var x, y int16 if ux > 32255 { @@ -417,7 +415,7 @@ func (b *Driver) handleLocatorDetected(data []uint8) { y = int16(uy) } - //create point obj + // create point obj p := new(Point2D) p.X = x p.Y = y @@ -428,7 +426,6 @@ func (b *Driver) handleLocatorDetected(data []uint8) { } func (b *Driver) handleCollisionDetected(data []uint8) { - if len(data) == ResponsePacketMaxSize { // Check if this is the header of collision response. (i.e. first part of data) // Collision response is 22 bytes long. (individual packet size is maxed at 20) diff --git a/platforms/sphero/ollie/ollie_driver_test.go b/platforms/sphero/ollie/ollie_driver_test.go index 847c48dcf..3116d5849 100644 --- a/platforms/sphero/ollie/ollie_driver_test.go +++ b/platforms/sphero/ollie/ollie_driver_test.go @@ -6,8 +6,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" "gobot.io/x/gobot/v2/platforms/sphero" ) @@ -21,13 +21,13 @@ func initTestOllieDriver() *Driver { func TestOllieDriver(t *testing.T) { d := initTestOllieDriver() d.SetName("NewName") - gobottest.Assert(t, d.Name(), "NewName") + assert.Equal(t, "NewName", d.Name()) } func TestOllieDriverStartAndHalt(t *testing.T) { d := initTestOllieDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Halt()) } func TestLocatorData(t *testing.T) { @@ -49,11 +49,11 @@ func TestLocatorData(t *testing.T) { } for _, point := range tables { - //0x0B is the locator ID + // 0x0B is the locator ID packet := []byte{0xFF, 0xFF, 0x00, 0x00, 0x0B, point.x1, point.x2, point.y1, point.y2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} d.GetLocatorData(func(p Point2D) { - gobottest.Assert(t, p.Y, point.y) + assert.Equal(t, point.y, p.Y) }) d.HandleResponses(packet, nil) } @@ -68,12 +68,13 @@ func TestDataStreaming(t *testing.T) { _ = d.On("sensordata", func(data interface{}) { cont := data.(DataStreamingPacket) fmt.Printf("got streaming packet: %+v \n", cont) - gobottest.Assert(t, cont.RawAccX, int16(10)) + assert.Equal(t, int16(10), cont.RawAccX) response = true }) - //example data packet - p1 := []string{"FFFE030053000A003900FAFFFE0007FFFF000000", + // example data packet + p1 := []string{ + "FFFE030053000A003900FAFFFE0007FFFF000000", "000000000000000000FFECFFFB00010000004B01", "BD1034FFFF000300000000000000000000000000", "0000002701FDE500560000000000000065000000", @@ -92,10 +93,10 @@ func TestDataStreaming(t *testing.T) { } - //send empty packet to indicate start of next message + // send empty packet to indicate start of next message d.HandleResponses([]byte{0xFF}, nil) time.Sleep(10 * time.Millisecond) if response == false { - t.Error("no response recieved") + t.Error("no response received") } } diff --git a/platforms/sphero/ollie/ollie_packets.go b/platforms/sphero/ollie/ollie_packets.go index 06c43e34f..673c18954 100644 --- a/platforms/sphero/ollie/ollie_packets.go +++ b/platforms/sphero/ollie/ollie_packets.go @@ -24,7 +24,7 @@ type PowerStatePacket struct { BattVoltage uint16 // Number of charges in the total lifetime of the sphero NumCharges uint16 - //Seconds awake since last charge + // Seconds awake since last charge TimeSinceChg uint16 } diff --git a/platforms/sphero/sphero_adaptor_test.go b/platforms/sphero/sphero_adaptor_test.go index cd9403359..1ca2a7205 100644 --- a/platforms/sphero/sphero_adaptor_test.go +++ b/platforms/sphero/sphero_adaptor_test.go @@ -6,8 +6,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Adaptor = (*Adaptor)(nil) @@ -56,49 +56,49 @@ func initTestSpheroAdaptor() (*Adaptor, *nullReadWriteCloser) { func TestSpheroAdaptorName(t *testing.T) { a, _ := initTestSpheroAdaptor() - gobottest.Assert(t, strings.HasPrefix(a.Name(), "Sphero"), true) + assert.True(t, strings.HasPrefix(a.Name(), "Sphero")) a.SetName("NewName") - gobottest.Assert(t, a.Name(), "NewName") + assert.Equal(t, "NewName", a.Name()) } func TestSpheroAdaptor(t *testing.T) { a, _ := initTestSpheroAdaptor() - gobottest.Assert(t, strings.HasPrefix(a.Name(), "Sphero"), true) - gobottest.Assert(t, a.Port(), "/dev/null") + assert.True(t, strings.HasPrefix(a.Name(), "Sphero")) + assert.Equal(t, "/dev/null", a.Port()) } func TestSpheroAdaptorReconnect(t *testing.T) { a, _ := initTestSpheroAdaptor() _ = a.Connect() - gobottest.Assert(t, a.connected, true) + assert.True(t, a.connected) _ = a.Reconnect() - gobottest.Assert(t, a.connected, true) + assert.True(t, a.connected) _ = a.Disconnect() - gobottest.Assert(t, a.connected, false) + assert.False(t, a.connected) _ = a.Reconnect() - gobottest.Assert(t, a.connected, true) + assert.True(t, a.connected) } func TestSpheroAdaptorFinalize(t *testing.T) { a, rwc := initTestSpheroAdaptor() _ = a.Connect() - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) rwc.testAdaptorClose = func() error { return errors.New("close error") } a.connected = true - gobottest.Assert(t, a.Finalize(), errors.New("close error")) + assert.ErrorContains(t, a.Finalize(), "close error") } func TestSpheroAdaptorConnect(t *testing.T) { a, _ := initTestSpheroAdaptor() - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) a.connect = func(string) (io.ReadWriteCloser, error) { return nil, errors.New("connect error") } - gobottest.Assert(t, a.Connect(), errors.New("connect error")) + assert.ErrorContains(t, a.Connect(), "connect error") } diff --git a/platforms/sphero/sphero_driver.go b/platforms/sphero/sphero_driver.go index 04b74f426..b2e9d48ae 100644 --- a/platforms/sphero/sphero_driver.go +++ b/platforms/sphero/sphero_driver.go @@ -37,6 +37,7 @@ type SpheroDriver struct { syncResponse [][]uint8 packetChannel chan *packet responseChannel chan []uint8 + originalColor []uint8 // Only used for calibration. gobot.Eventer gobot.Commander } @@ -322,6 +323,40 @@ func (s *SpheroDriver) ConfigureCollisionDetection(cc CollisionConfig) { s.packetChannel <- s.craftPacket([]uint8{cc.Method, cc.Xt, cc.Yt, cc.Xs, cc.Ys, cc.Dead}, 0x02, 0x12) } +// SetCalibration sets up Sphero for manual heading calibration. +// It does this by turning on the tail light (so you can tell where it's +// facing) and disabling stabilization (so you can adjust the heading). +// +// When done, call FinishCalibration to set the new heading, and re-enable +// stabilization. +func (s *SpheroDriver) StartCalibration() { + s.mtx.Lock() + s.originalColor = s.GetRGB() + s.SetRGB(0, 0, 0) + s.SetBackLED(127) + s.SetStabilization(false) + s.mtx.Unlock() +} + +// FinishCalibration ends Sphero's calibration mode, by setting +// the new heading as current, and re-enabling normal defaults. This is a NOP +// in case StartCalibration was not called. +func (s *SpheroDriver) FinishCalibration() { + s.mtx.Lock() + if s.originalColor == nil { + // Piggybacking on the original color being set to know if we are + // calibrating or not. + return + } + + s.SetHeading(0) + s.SetRGB(s.originalColor[0], s.originalColor[1], s.originalColor[2]) + s.SetBackLED(0) + s.SetStabilization(true) + s.originalColor = nil + s.mtx.Unlock() +} + func (s *SpheroDriver) enableStopOnDisconnect() { s.packetChannel <- s.craftPacket([]uint8{0x00, 0x00, 0x00, 0x01}, 0x02, 0x37) } @@ -368,7 +403,7 @@ func (s *SpheroDriver) getSyncResponse(packet *packet) []byte { return []byte{} } -func (s *SpheroDriver) craftPacket(body []uint8, did byte, cid byte) *packet { +func (s *SpheroDriver) craftPacket(body []uint8, did byte, cid byte) *packet { //nolint:unparam // keep did as parameter s.mtx.Lock() defer s.mtx.Unlock() packet := new(packet) diff --git a/platforms/sphero/sphero_driver_test.go b/platforms/sphero/sphero_driver_test.go index 28a3d79f7..879455c62 100644 --- a/platforms/sphero/sphero_driver_test.go +++ b/platforms/sphero/sphero_driver_test.go @@ -6,8 +6,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*SpheroDriver)(nil) @@ -20,9 +20,9 @@ func initTestSpheroDriver() *SpheroDriver { func TestSpheroDriverName(t *testing.T) { d := initTestSpheroDriver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "Sphero"), true) + assert.True(t, strings.HasPrefix(d.Name(), "Sphero")) d.SetName("NewName") - gobottest.Assert(t, d.Name(), "NewName") + assert.Equal(t, "NewName", d.Name()) } func TestSpheroDriver(t *testing.T) { @@ -32,65 +32,65 @@ func TestSpheroDriver(t *testing.T) { ret = d.Command("SetRGB")( map[string]interface{}{"r": 100.0, "g": 100.0, "b": 100.0}, ) - gobottest.Assert(t, ret, nil) + assert.Nil(t, ret) ret = d.Command("Roll")( map[string]interface{}{"speed": 100.0, "heading": 100.0}, ) - gobottest.Assert(t, ret, nil) + assert.Nil(t, ret) ret = d.Command("SetBackLED")( map[string]interface{}{"level": 100.0}, ) - gobottest.Assert(t, ret, nil) + assert.Nil(t, ret) ret = d.Command("ConfigureLocator")( map[string]interface{}{"Flags": 1.0, "X": 100.0, "Y": 100.0, "YawTare": 100.0}, ) - gobottest.Assert(t, ret, nil) + assert.Nil(t, ret) ret = d.Command("SetHeading")( map[string]interface{}{"heading": 100.0}, ) - gobottest.Assert(t, ret, nil) + assert.Nil(t, ret) ret = d.Command("SetRotationRate")( map[string]interface{}{"level": 100.0}, ) - gobottest.Assert(t, ret, nil) + assert.Nil(t, ret) ret = d.Command("SetStabilization")( map[string]interface{}{"enable": true}, ) - gobottest.Assert(t, ret, nil) + assert.Nil(t, ret) ret = d.Command("SetStabilization")( map[string]interface{}{"enable": false}, ) - gobottest.Assert(t, ret, nil) + assert.Nil(t, ret) ret = d.Command("Stop")(nil) - gobottest.Assert(t, ret, nil) + assert.Nil(t, ret) ret = d.Command("GetRGB")(nil) - gobottest.Assert(t, ret.([]byte), []byte{}) + assert.Equal(t, []byte{}, ret.([]byte)) ret = d.Command("ReadLocator")(nil) - gobottest.Assert(t, ret, []int16{}) + assert.Equal(t, []int16{}, ret) - gobottest.Assert(t, strings.HasPrefix(d.Name(), "Sphero"), true) - gobottest.Assert(t, strings.HasPrefix(d.Connection().Name(), "Sphero"), true) + assert.True(t, strings.HasPrefix(d.Name(), "Sphero")) + assert.True(t, strings.HasPrefix(d.Connection().Name(), "Sphero")) } func TestSpheroDriverStart(t *testing.T) { d := initTestSpheroDriver() - gobottest.Assert(t, d.Start(), nil) + assert.NoError(t, d.Start()) } func TestSpheroDriverHalt(t *testing.T) { d := initTestSpheroDriver() d.adaptor().connected = true - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Halt()) } func TestSpheroDriverSetDataStreaming(t *testing.T) { @@ -102,7 +102,7 @@ func TestSpheroDriverSetDataStreaming(t *testing.T) { buf := new(bytes.Buffer) _ = binary.Write(buf, binary.BigEndian, DefaultDataStreamingConfig()) - gobottest.Assert(t, data.body, buf.Bytes()) + assert.Equal(t, buf.Bytes(), data.body) ret := d.Command("SetDataStreaming")( map[string]interface{}{ @@ -113,14 +113,14 @@ func TestSpheroDriverSetDataStreaming(t *testing.T) { "Mask2": 400.0, }, ) - gobottest.Assert(t, ret, nil) + assert.Nil(t, ret) data = <-d.packetChannel dconfig := DataStreamingConfig{N: 100, M: 200, Mask: 300, Pcnt: 255, Mask2: 400} buf = new(bytes.Buffer) _ = binary.Write(buf, binary.BigEndian, dconfig) - gobottest.Assert(t, data.body, buf.Bytes()) + assert.Equal(t, buf.Bytes(), data.body) } func TestConfigureLocator(t *testing.T) { @@ -131,7 +131,7 @@ func TestConfigureLocator(t *testing.T) { buf := new(bytes.Buffer) _ = binary.Write(buf, binary.BigEndian, DefaultLocatorConfig()) - gobottest.Assert(t, data.body, buf.Bytes()) + assert.Equal(t, buf.Bytes(), data.body) ret := d.Command("ConfigureLocator")( map[string]interface{}{ @@ -141,14 +141,14 @@ func TestConfigureLocator(t *testing.T) { "YawTare": 0.0, }, ) - gobottest.Assert(t, ret, nil) + assert.Nil(t, ret) data = <-d.packetChannel lconfig := LocatorConfig{Flags: 1, X: 100, Y: 100, YawTare: 0} buf = new(bytes.Buffer) _ = binary.Write(buf, binary.BigEndian, lconfig) - gobottest.Assert(t, data.body, buf.Bytes()) + assert.Equal(t, buf.Bytes(), data.body) } func TestCalculateChecksum(t *testing.T) { diff --git a/platforms/sphero/sprkplus/sprkplus_driver_test.go b/platforms/sphero/sprkplus/sprkplus_driver_test.go index 6bb1ed2d2..80097850f 100644 --- a/platforms/sphero/sprkplus/sprkplus_driver_test.go +++ b/platforms/sphero/sprkplus/sprkplus_driver_test.go @@ -4,8 +4,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.Driver = (*SPRKPlusDriver)(nil) @@ -17,13 +17,13 @@ func initTestSPRKPlusDriver() *SPRKPlusDriver { func TestSPRKPlusDriver(t *testing.T) { d := initTestSPRKPlusDriver() - gobottest.Assert(t, strings.HasPrefix(d.Name(), "SPRK"), true) + assert.True(t, strings.HasPrefix(d.Name(), "SPRK")) d.SetName("NewName") - gobottest.Assert(t, d.Name(), "NewName") + assert.Equal(t, "NewName", d.Name()) } func TestSPRKPlusDriverStartAndHalt(t *testing.T) { d := initTestSPRKPlusDriver() - gobottest.Assert(t, d.Start(), nil) - gobottest.Assert(t, d.Halt(), nil) + assert.NoError(t, d.Start()) + assert.NoError(t, d.Halt()) } diff --git a/platforms/tinkerboard/adaptor_test.go b/platforms/tinkerboard/adaptor_test.go index c25ae6145..14a9dae1c 100644 --- a/platforms/tinkerboard/adaptor_test.go +++ b/platforms/tinkerboard/adaptor_test.go @@ -5,10 +5,10 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" "gobot.io/x/gobot/v2/drivers/gpio" "gobot.io/x/gobot/v2/drivers/i2c" - "gobot.io/x/gobot/v2/gobottest" "gobot.io/x/gobot/v2/system" ) @@ -18,7 +18,7 @@ const ( ) const ( - pwmDir = "/sys/devices/platform/ff680020.pwm/pwm/pwmchip2/" + pwmDir = "/sys/devices/platform/ff680020.pwm/pwm/pwmchip2/" //nolint:gosec // false positive pwmPwmDir = pwmDir + "pwm0/" pwmExportPath = pwmDir + "export" pwmUnexportPath = pwmDir + "unexport" @@ -47,14 +47,16 @@ var gpioMockPaths = []string{ } // make sure that this Adaptor fulfills all the required interfaces -var _ gobot.Adaptor = (*Adaptor)(nil) -var _ gobot.DigitalPinnerProvider = (*Adaptor)(nil) -var _ gobot.PWMPinnerProvider = (*Adaptor)(nil) -var _ gpio.DigitalReader = (*Adaptor)(nil) -var _ gpio.DigitalWriter = (*Adaptor)(nil) -var _ gpio.PwmWriter = (*Adaptor)(nil) -var _ gpio.ServoWriter = (*Adaptor)(nil) -var _ i2c.Connector = (*Adaptor)(nil) +var ( + _ gobot.Adaptor = (*Adaptor)(nil) + _ gobot.DigitalPinnerProvider = (*Adaptor)(nil) + _ gobot.PWMPinnerProvider = (*Adaptor)(nil) + _ gpio.DigitalReader = (*Adaptor)(nil) + _ gpio.DigitalWriter = (*Adaptor)(nil) + _ gpio.PwmWriter = (*Adaptor)(nil) + _ gpio.ServoWriter = (*Adaptor)(nil) + _ i2c.Connector = (*Adaptor)(nil) +) func preparePwmFs(fs *system.MockFilesystem) { fs.Files[pwmEnablePath].Contents = "0" @@ -74,9 +76,9 @@ func initTestAdaptorWithMockedFilesystem(mockPaths []string) (*Adaptor, *system. func TestName(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, strings.HasPrefix(a.Name(), "Tinker Board"), true) + assert.True(t, strings.HasPrefix(a.Name(), "Tinker Board")) a.SetName("NewName") - gobottest.Assert(t, a.Name(), "NewName") + assert.Equal(t, "NewName", a.Name()) } func TestDigitalIO(t *testing.T) { @@ -84,14 +86,14 @@ func TestDigitalIO(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem(gpioMockPaths) _ = a.DigitalWrite("7", 1) - gobottest.Assert(t, fs.Files[gpio17Path+"value"].Contents, "1") + assert.Equal(t, "1", fs.Files[gpio17Path+"value"].Contents) fs.Files[gpio160Path+"value"].Contents = "1" i, _ := a.DigitalRead("10") - gobottest.Assert(t, i, 1) + assert.Equal(t, 1, i) - gobottest.Assert(t, a.DigitalWrite("99", 1), fmt.Errorf("'99' is not a valid id for a digital pin")) - gobottest.Assert(t, a.Finalize(), nil) + assert.ErrorContains(t, a.DigitalWrite("99", 1), "'99' is not a valid id for a digital pin") + assert.NoError(t, a.Finalize()) } func TestInvalidPWMPin(t *testing.T) { @@ -99,16 +101,16 @@ func TestInvalidPWMPin(t *testing.T) { preparePwmFs(fs) err := a.PwmWrite("666", 42) - gobottest.Assert(t, err.Error(), "'666' is not a valid id for a PWM pin") + assert.ErrorContains(t, err, "'666' is not a valid id for a PWM pin") err = a.ServoWrite("666", 120) - gobottest.Assert(t, err.Error(), "'666' is not a valid id for a PWM pin") + assert.ErrorContains(t, err, "'666' is not a valid id for a PWM pin") err = a.PwmWrite("3", 42) - gobottest.Assert(t, err.Error(), "'3' is not a valid id for a PWM pin") + assert.ErrorContains(t, err, "'3' is not a valid id for a PWM pin") err = a.ServoWrite("3", 120) - gobottest.Assert(t, err.Error(), "'3' is not a valid id for a PWM pin") + assert.ErrorContains(t, err, "'3' is not a valid id for a PWM pin") } func TestPwmWrite(t *testing.T) { @@ -116,24 +118,24 @@ func TestPwmWrite(t *testing.T) { preparePwmFs(fs) err := a.PwmWrite("33", 100) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) - gobottest.Assert(t, fs.Files[pwmExportPath].Contents, "0") - gobottest.Assert(t, fs.Files[pwmEnablePath].Contents, "1") - gobottest.Assert(t, fs.Files[pwmPeriodPath].Contents, fmt.Sprintf("%d", 10000000)) - gobottest.Assert(t, fs.Files[pwmDutyCyclePath].Contents, "3921568") - gobottest.Assert(t, fs.Files[pwmPolarityPath].Contents, "normal") + assert.Equal(t, "0", fs.Files[pwmExportPath].Contents) + assert.Equal(t, "1", fs.Files[pwmEnablePath].Contents) + assert.Equal(t, fmt.Sprintf("%d", 10000000), fs.Files[pwmPeriodPath].Contents) + assert.Equal(t, "3921568", fs.Files[pwmDutyCyclePath].Contents) + assert.Equal(t, "normal", fs.Files[pwmPolarityPath].Contents) err = a.ServoWrite("33", 0) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) - gobottest.Assert(t, fs.Files[pwmDutyCyclePath].Contents, "500000") + assert.Equal(t, "500000", fs.Files[pwmDutyCyclePath].Contents) err = a.ServoWrite("33", 180) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) - gobottest.Assert(t, fs.Files[pwmDutyCyclePath].Contents, "2000000") - gobottest.Assert(t, a.Finalize(), nil) + assert.Equal(t, "2000000", fs.Files[pwmDutyCyclePath].Contents) + assert.NoError(t, a.Finalize()) } func TestSetPeriod(t *testing.T) { @@ -145,25 +147,25 @@ func TestSetPeriod(t *testing.T) { // act err := a.SetPeriod("33", newPeriod) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files[pwmExportPath].Contents, "0") - gobottest.Assert(t, fs.Files[pwmEnablePath].Contents, "1") - gobottest.Assert(t, fs.Files[pwmPeriodPath].Contents, fmt.Sprintf("%d", newPeriod)) - gobottest.Assert(t, fs.Files[pwmDutyCyclePath].Contents, "0") - gobottest.Assert(t, fs.Files[pwmPolarityPath].Contents, "normal") + assert.NoError(t, err) + assert.Equal(t, "0", fs.Files[pwmExportPath].Contents) + assert.Equal(t, "1", fs.Files[pwmEnablePath].Contents) + assert.Equal(t, fmt.Sprintf("%d", newPeriod), fs.Files[pwmPeriodPath].Contents) + assert.Equal(t, "0", fs.Files[pwmDutyCyclePath].Contents) + assert.Equal(t, "normal", fs.Files[pwmPolarityPath].Contents) // arrange test for automatic adjustment of duty cycle to lower value err = a.PwmWrite("33", 127) // 127 is a little bit smaller than 50% of period - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files[pwmDutyCyclePath].Contents, fmt.Sprintf("%d", 1270000)) + assert.NoError(t, err) + assert.Equal(t, fmt.Sprintf("%d", 1270000), fs.Files[pwmDutyCyclePath].Contents) newPeriod = newPeriod / 10 // act err = a.SetPeriod("33", newPeriod) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files[pwmDutyCyclePath].Contents, fmt.Sprintf("%d", 127000)) + assert.NoError(t, err) + assert.Equal(t, fmt.Sprintf("%d", 127000), fs.Files[pwmDutyCyclePath].Contents) // arrange test for automatic adjustment of duty cycle to higher value newPeriod = newPeriod * 20 @@ -172,46 +174,46 @@ func TestSetPeriod(t *testing.T) { err = a.SetPeriod("33", newPeriod) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files[pwmDutyCyclePath].Contents, fmt.Sprintf("%d", 2540000)) + assert.NoError(t, err) + assert.Equal(t, fmt.Sprintf("%d", 2540000), fs.Files[pwmDutyCyclePath].Contents) } func TestFinalizeErrorAfterGPIO(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem(gpioMockPaths) - gobottest.Assert(t, a.DigitalWrite("7", 1), nil) + assert.NoError(t, a.DigitalWrite("7", 1)) fs.WithWriteError = true err := a.Finalize() - gobottest.Assert(t, strings.Contains(err.Error(), "write error"), true) + assert.Contains(t, err.Error(), "write error") } func TestFinalizeErrorAfterPWM(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem(pwmMockPaths) preparePwmFs(fs) - gobottest.Assert(t, a.PwmWrite("33", 1), nil) + assert.NoError(t, a.PwmWrite("33", 1)) fs.WithWriteError = true err := a.Finalize() - gobottest.Assert(t, strings.Contains(err.Error(), "write error"), true) + assert.Contains(t, err.Error(), "write error") } func TestSpiDefaultValues(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, a.SpiDefaultBusNumber(), 0) - gobottest.Assert(t, a.SpiDefaultChipNumber(), 0) - gobottest.Assert(t, a.SpiDefaultMode(), 0) - gobottest.Assert(t, a.SpiDefaultBitCount(), 8) - gobottest.Assert(t, a.SpiDefaultMaxSpeed(), int64(500000)) + assert.Equal(t, 0, a.SpiDefaultBusNumber()) + assert.Equal(t, 0, a.SpiDefaultChipNumber()) + assert.Equal(t, 0, a.SpiDefaultMode()) + assert.Equal(t, 8, a.SpiDefaultBitCount()) + assert.Equal(t, int64(500000), a.SpiDefaultMaxSpeed()) } func TestI2cDefaultBus(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, a.DefaultI2cBus(), 1) + assert.Equal(t, 1, a.DefaultI2cBus()) } func TestI2cFinalizeWithErrors(t *testing.T) { @@ -219,20 +221,20 @@ func TestI2cFinalizeWithErrors(t *testing.T) { a := NewAdaptor() a.sys.UseMockSyscall() fs := a.sys.UseMockFilesystem([]string{"/dev/i2c-4"}) - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) con, err := a.GetI2cConnection(0xff, 4) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) _, err = con.Write([]byte{0xbf}) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) fs.WithCloseError = true // act err = a.Finalize() // assert - gobottest.Assert(t, strings.Contains(err.Error(), "close error"), true) + assert.Contains(t, err.Error(), "close error") } func Test_validateSpiBusNumber(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { busNr int wantErr error }{ @@ -262,13 +264,13 @@ func Test_validateSpiBusNumber(t *testing.T) { // act err := a.validateSpiBusNumber(tc.busNr) // assert - gobottest.Assert(t, err, tc.wantErr) + assert.Equal(t, tc.wantErr, err) }) } } func Test_validateI2cBusNumber(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { busNr int wantErr error }{ @@ -303,13 +305,13 @@ func Test_validateI2cBusNumber(t *testing.T) { // act err := a.validateI2cBusNumber(tc.busNr) // assert - gobottest.Assert(t, err, tc.wantErr) + assert.Equal(t, tc.wantErr, err) }) } } func Test_translateDigitalPin(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { access string pin string wantChip string @@ -343,9 +345,9 @@ func Test_translateDigitalPin(t *testing.T) { // act chip, line, err := a.translateDigitalPin(tc.pin) // assert - gobottest.Assert(t, err, tc.wantErr) - gobottest.Assert(t, chip, tc.wantChip) - gobottest.Assert(t, line, tc.wantLine) + assert.Equal(t, tc.wantErr, err) + assert.Equal(t, tc.wantChip, chip) + assert.Equal(t, tc.wantLine, line) }) } } @@ -355,7 +357,7 @@ func Test_translatePWMPin(t *testing.T) { "/sys/devices/platform/ff680020.pwm/pwm/", "/sys/devices/platform/ff680030.pwm/pwm/", } - var tests = map[string]struct { + tests := map[string]struct { pin string chip string wantDir string @@ -422,9 +424,9 @@ func Test_translatePWMPin(t *testing.T) { // act dir, channel, err := a.translatePWMPin(tc.pin) // assert - gobottest.Assert(t, err, tc.wantErr) - gobottest.Assert(t, dir, tc.wantDir) - gobottest.Assert(t, channel, tc.wantChannel) + assert.Equal(t, tc.wantErr, err) + assert.Equal(t, tc.wantDir, dir) + assert.Equal(t, tc.wantChannel, channel) }) } } diff --git a/platforms/upboard/up2/adaptor.go b/platforms/upboard/up2/adaptor.go index 19478ab27..5f0360b00 100644 --- a/platforms/upboard/up2/adaptor.go +++ b/platforms/upboard/up2/adaptor.go @@ -125,7 +125,7 @@ func (c *Adaptor) DigitalWrite(id string, val byte) error { // is it one of the built-in LEDs? if id == LEDRed || id == LEDBlue || id == LEDGreen || id == LEDYellow { pinPath := fmt.Sprintf(c.ledPath, id) - fi, err := c.sys.OpenFile(pinPath, os.O_WRONLY|os.O_APPEND, 0666) + fi, err := c.sys.OpenFile(pinPath, os.O_WRONLY|os.O_APPEND, 0o666) defer fi.Close() //nolint:staticcheck // for historical reasons if err != nil { return err @@ -170,5 +170,4 @@ func (c *Adaptor) translatePWMPin(id string) (string, int, error) { return "", -1, fmt.Errorf("'%s' is not a valid id for a PWM pin", id) } return "/sys/class/pwm/pwmchip0", sysPin.pwmPin, nil - } diff --git a/platforms/upboard/up2/adaptor_test.go b/platforms/upboard/up2/adaptor_test.go index 83ac48334..859a324a5 100644 --- a/platforms/upboard/up2/adaptor_test.go +++ b/platforms/upboard/up2/adaptor_test.go @@ -1,29 +1,30 @@ package up2 import ( - "errors" "fmt" "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" "gobot.io/x/gobot/v2/drivers/gpio" "gobot.io/x/gobot/v2/drivers/i2c" "gobot.io/x/gobot/v2/drivers/spi" - "gobot.io/x/gobot/v2/gobottest" "gobot.io/x/gobot/v2/system" ) // make sure that this Adaptor fulfills all the required interfaces -var _ gobot.Adaptor = (*Adaptor)(nil) -var _ gobot.DigitalPinnerProvider = (*Adaptor)(nil) -var _ gobot.PWMPinnerProvider = (*Adaptor)(nil) -var _ gpio.DigitalReader = (*Adaptor)(nil) -var _ gpio.DigitalWriter = (*Adaptor)(nil) -var _ gpio.PwmWriter = (*Adaptor)(nil) -var _ gpio.ServoWriter = (*Adaptor)(nil) -var _ i2c.Connector = (*Adaptor)(nil) -var _ spi.Connector = (*Adaptor)(nil) +var ( + _ gobot.Adaptor = (*Adaptor)(nil) + _ gobot.DigitalPinnerProvider = (*Adaptor)(nil) + _ gobot.PWMPinnerProvider = (*Adaptor)(nil) + _ gpio.DigitalReader = (*Adaptor)(nil) + _ gpio.DigitalWriter = (*Adaptor)(nil) + _ gpio.PwmWriter = (*Adaptor)(nil) + _ gpio.ServoWriter = (*Adaptor)(nil) + _ i2c.Connector = (*Adaptor)(nil) + _ spi.Connector = (*Adaptor)(nil) +) var pwmMockPaths = []string{ "/sys/class/pwm/pwmchip0/export", @@ -55,86 +56,94 @@ func initTestAdaptorWithMockedFilesystem(mockPaths []string) (*Adaptor, *system. func TestName(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, strings.HasPrefix(a.Name(), "UP2"), true) + assert.True(t, strings.HasPrefix(a.Name(), "UP2")) a.SetName("NewName") - gobottest.Assert(t, a.Name(), "NewName") + assert.Equal(t, "NewName", a.Name()) } func TestDigitalIO(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem(gpioMockPaths) _ = a.DigitalWrite("7", 1) - gobottest.Assert(t, fs.Files["/sys/class/gpio/gpio462/value"].Contents, "1") + assert.Equal(t, "1", fs.Files["/sys/class/gpio/gpio462/value"].Contents) fs.Files["/sys/class/gpio/gpio432/value"].Contents = "1" i, _ := a.DigitalRead("13") - gobottest.Assert(t, i, 1) + assert.Equal(t, 1, i) _ = a.DigitalWrite("green", 1) - gobottest.Assert(t, - fs.Files["/sys/class/leds/upboard:green:/brightness"].Contents, + assert.Equal(t, "1", + fs.Files["/sys/class/leds/upboard:green:/brightness"].Contents, ) - gobottest.Assert(t, a.DigitalWrite("99", 1), errors.New("'99' is not a valid id for a digital pin")) - gobottest.Assert(t, a.Finalize(), nil) + assert.ErrorContains(t, a.DigitalWrite("99", 1), "'99' is not a valid id for a digital pin") + assert.NoError(t, a.Finalize()) } func TestPWM(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem(pwmMockPaths) + fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents = "0" + fs.Files["/sys/class/pwm/pwmchip0/pwm0/period"].Contents = "0" err := a.PwmWrite("32", 100) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) - gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/export"].Contents, "0") - gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm0/enable"].Contents, "1") - gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents, "3921568") - gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm0/polarity"].Contents, "normal") + assert.Equal(t, "0", fs.Files["/sys/class/pwm/pwmchip0/export"].Contents) + assert.Equal(t, "1", fs.Files["/sys/class/pwm/pwmchip0/pwm0/enable"].Contents) + assert.Equal(t, "3921568", fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents) + assert.Equal(t, "10000000", fs.Files["/sys/class/pwm/pwmchip0/pwm0/period"].Contents) // pwmPeriodDefault + assert.Equal(t, "normal", fs.Files["/sys/class/pwm/pwmchip0/pwm0/polarity"].Contents) err = a.ServoWrite("32", 0) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) - gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents, "500000") + assert.Equal(t, "500000", fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents) + assert.Equal(t, "10000000", fs.Files["/sys/class/pwm/pwmchip0/pwm0/period"].Contents) err = a.ServoWrite("32", 180) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) + + assert.Equal(t, "2000000", fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents) + assert.Equal(t, "10000000", fs.Files["/sys/class/pwm/pwmchip0/pwm0/period"].Contents) - gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents, "2000000") - gobottest.Assert(t, a.Finalize(), nil) + assert.NoError(t, a.Finalize()) } func TestFinalizeErrorAfterGPIO(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem(gpioMockPaths) - gobottest.Assert(t, a.DigitalWrite("7", 1), nil) + assert.NoError(t, a.DigitalWrite("7", 1)) fs.WithWriteError = true err := a.Finalize() - gobottest.Assert(t, strings.Contains(err.Error(), "write error"), true) + assert.Contains(t, err.Error(), "write error") } func TestFinalizeErrorAfterPWM(t *testing.T) { a, fs := initTestAdaptorWithMockedFilesystem(pwmMockPaths) + fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents = "0" + fs.Files["/sys/class/pwm/pwmchip0/pwm0/period"].Contents = "0" - gobottest.Assert(t, a.PwmWrite("32", 1), nil) + assert.NoError(t, a.PwmWrite("32", 1)) fs.WithWriteError = true err := a.Finalize() - gobottest.Assert(t, strings.Contains(err.Error(), "write error"), true) + assert.Contains(t, err.Error(), "write error") } func TestSpiDefaultValues(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, a.SpiDefaultBusNumber(), 0) - gobottest.Assert(t, a.SpiDefaultMode(), 0) - gobottest.Assert(t, a.SpiDefaultMaxSpeed(), int64(500000)) + assert.Equal(t, 0, a.SpiDefaultBusNumber()) + assert.Equal(t, 0, a.SpiDefaultMode()) + assert.Equal(t, int64(500000), a.SpiDefaultMaxSpeed()) } func Test_validateSpiBusNumber(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { busNr int wantErr error }{ @@ -160,14 +169,14 @@ func Test_validateSpiBusNumber(t *testing.T) { // act err := a.validateSpiBusNumber(tc.busNr) // assert - gobottest.Assert(t, err, tc.wantErr) + assert.Equal(t, tc.wantErr, err) }) } } func TestI2cDefaultBus(t *testing.T) { a := NewAdaptor() - gobottest.Assert(t, a.DefaultI2cBus(), 5) + assert.Equal(t, 5, a.DefaultI2cBus()) } func TestI2cFinalizeWithErrors(t *testing.T) { @@ -175,20 +184,20 @@ func TestI2cFinalizeWithErrors(t *testing.T) { a := NewAdaptor() a.sys.UseMockSyscall() fs := a.sys.UseMockFilesystem([]string{"/dev/i2c-5"}) - gobottest.Assert(t, a.Connect(), nil) + assert.NoError(t, a.Connect()) con, err := a.GetI2cConnection(0xff, 5) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) _, err = con.Write([]byte{0xbf}) - gobottest.Assert(t, err, nil) + assert.NoError(t, err) fs.WithCloseError = true // act err = a.Finalize() // assert - gobottest.Assert(t, strings.Contains(err.Error(), "close error"), true) + assert.Contains(t, err.Error(), "close error") } func Test_validateI2cBusNumber(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { busNr int wantErr error }{ @@ -218,13 +227,13 @@ func Test_validateI2cBusNumber(t *testing.T) { // act err := a.validateI2cBusNumber(tc.busNr) // assert - gobottest.Assert(t, err, tc.wantErr) + assert.Equal(t, tc.wantErr, err) }) } } func Test_translatePWMPin(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { wantDir string wantChannel int wantErr error @@ -259,9 +268,9 @@ func Test_translatePWMPin(t *testing.T) { // act dir, channel, err := a.translatePWMPin(name) // assert - gobottest.Assert(t, err, tc.wantErr) - gobottest.Assert(t, dir, tc.wantDir) - gobottest.Assert(t, channel, tc.wantChannel) + assert.Equal(t, tc.wantErr, err) + assert.Equal(t, tc.wantDir, dir) + assert.Equal(t, tc.wantChannel, channel) }) } } diff --git a/robot.go b/robot.go index 6aa1283bf..647cd8b77 100644 --- a/robot.go +++ b/robot.go @@ -5,9 +5,8 @@ import ( "log" "os" "os/signal" - "sync/atomic" - "sync" + "sync/atomic" multierror "github.com/hashicorp/go-multierror" ) @@ -103,10 +102,10 @@ func (r *Robots) Each(f func(*Robot)) { // NewRobot returns a new Robot. It supports the following optional params: // -// name: string with the name of the Robot. A name will be automatically generated if no name is supplied. -// []Connection: Connections which are automatically started and stopped with the robot -// []Device: Devices which are automatically started and stopped with the robot -// func(): The work routine the robot will execute once all devices and connections have been initialized and started +// name: string with the name of the Robot. A name will be automatically generated if no name is supplied. +// []Connection: Connections which are automatically started and stopped with the robot +// []Device: Devices which are automatically started and stopped with the robot +// func(): The work routine the robot will execute once all devices and connections have been initialized and started func NewRobot(v ...interface{}) *Robot { r := &Robot{ Name: fmt.Sprintf("%X", Rand(int(^uint(0)>>1))), diff --git a/robot_test.go b/robot_test.go index 7bee3324a..dcf9df1cf 100644 --- a/robot_test.go +++ b/robot_test.go @@ -4,7 +4,7 @@ import ( "testing" "time" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) func TestRobotConnectionEach(t *testing.T) { @@ -14,7 +14,7 @@ func TestRobotConnectionEach(t *testing.T) { r.Connections().Each(func(conn Connection) { i++ }) - gobottest.Assert(t, r.Connections().Len(), i) + assert.Equal(t, i, r.Connections().Len()) } func TestRobotToJSON(t *testing.T) { @@ -23,45 +23,45 @@ func TestRobotToJSON(t *testing.T) { return nil }) json := NewJSONRobot(r) - gobottest.Assert(t, len(json.Devices), r.Devices().Len()) - gobottest.Assert(t, len(json.Commands), len(r.Commands())) + assert.Equal(t, r.Devices().Len(), len(json.Devices)) + assert.Equal(t, len(r.Commands()), len(json.Commands)) } func TestRobotDevicesToJSON(t *testing.T) { r := newTestRobot("Robot99") json := NewJSONRobot(r) - gobottest.Assert(t, len(json.Devices), r.Devices().Len()) - gobottest.Assert(t, json.Devices[0].Name, "Device1") - gobottest.Assert(t, json.Devices[0].Driver, "*gobot.testDriver") - gobottest.Assert(t, json.Devices[0].Connection, "Connection1") - gobottest.Assert(t, len(json.Devices[0].Commands), 1) + assert.Equal(t, r.Devices().Len(), len(json.Devices)) + assert.Equal(t, "Device1", json.Devices[0].Name) + assert.Equal(t, "*gobot.testDriver", json.Devices[0].Driver) + assert.Equal(t, "Connection1", json.Devices[0].Connection) + assert.Equal(t, 1, len(json.Devices[0].Commands)) } func TestRobotStart(t *testing.T) { r := newTestRobot("Robot99") - gobottest.Assert(t, r.Start(), nil) - gobottest.Assert(t, r.Stop(), nil) - gobottest.Assert(t, r.Running(), false) + assert.NoError(t, r.Start()) + assert.NoError(t, r.Stop()) + assert.False(t, r.Running()) } func TestRobotStartAutoRun(t *testing.T) { adaptor1 := newTestAdaptor("Connection1", "/dev/null") driver1 := newTestDriver(adaptor1, "Device1", "0") - //work := func() {} + // work := func() {} r := NewRobot("autorun", []Connection{adaptor1}, []Device{driver1}, - //work, + // work, ) go func() { - gobottest.Assert(t, r.Start(), nil) + assert.NoError(t, r.Start()) }() time.Sleep(10 * time.Millisecond) - gobottest.Assert(t, r.Running(), true) + assert.True(t, r.Running()) // stop it - gobottest.Assert(t, r.Stop(), nil) - gobottest.Assert(t, r.Running(), false) + assert.NoError(t, r.Stop()) + assert.False(t, r.Running()) } diff --git a/robot_work.go b/robot_work.go index 516b3a59d..b3a4e4ac7 100644 --- a/robot_work.go +++ b/robot_work.go @@ -3,9 +3,8 @@ package gobot import ( "context" "fmt" - "time" - "sync" + "time" "github.com/gofrs/uuid" ) @@ -30,7 +29,7 @@ const ( // // someWork := myRobot.Every(context.Background(), time.Second * 2, func(){ // fmt.Println("Here I am doing work") -// }) +// }) // // someWork.CallCancelFunc() // Cancel next tick and remove from work registry // @@ -38,7 +37,7 @@ const ( // // someWork2 := myRobot.Every(context.Background(), time.Second * 2, func(){ // fmt.Println("Here I am doing more work") -// }) +// }) // // somework2.CallCancelFunc() // diff --git a/robot_work_test.go b/robot_work_test.go index 36ed3b4bd..53f401033 100644 --- a/robot_work_test.go +++ b/robot_work_test.go @@ -3,7 +3,6 @@ package gobot import ( "context" "testing" - "time" "github.com/gofrs/uuid" diff --git a/system/GPIO.md b/system/GPIO.md index ee9586c0c..e2a4fae1c 100644 --- a/system/GPIO.md +++ b/system/GPIO.md @@ -142,6 +142,28 @@ Connect the input header pin26 to +3.3V with an resistor (e.g. 1kOhm). 1 ``` +### Test edge detection behavior of gpio251 (sysfs Tinkerboard) + +investigate status: + +```sh +# cat /sys/class/gpio/gpio251/edge +none +``` + +The file exists only if the pin can be configured as an interrupt generating input pin. To activate edge detection, +"rising", "falling", or "both" needs to be set. + +```sh +# cat /sys/class/gpio/gpio251/value +1 +``` + +If edge detection is activated, a poll will return only when the interrupt was triggered. The new value is written to +the beginning of the file. + +> Not tested yet, not supported by gobot yet. + ### Test output behavior of gpio251 (sysfs Tinkerboard) Connect the output header pin26 to +3.3V with an resistor (e.g. 1kOhm leads to ~0.3mA, 300Ohm leads to ~10mA). diff --git a/system/digitalpin_access.go b/system/digitalpin_access.go index f5d29befb..9ba351338 100644 --- a/system/digitalpin_access.go +++ b/system/digitalpin_access.go @@ -23,7 +23,8 @@ func (h *sysfsDigitalPinAccess) isSupported() bool { } func (h *sysfsDigitalPinAccess) createPin(chip string, pin int, - o ...func(gobot.DigitalPinOptioner) bool) gobot.DigitalPinner { + o ...func(gobot.DigitalPinOptioner) bool, +) gobot.DigitalPinner { return newDigitalPinSysfs(h.fs, strconv.Itoa(pin), o...) } @@ -41,7 +42,8 @@ func (h *gpiodDigitalPinAccess) isSupported() bool { } func (h *gpiodDigitalPinAccess) createPin(chip string, pin int, - o ...func(gobot.DigitalPinOptioner) bool) gobot.DigitalPinner { + o ...func(gobot.DigitalPinOptioner) bool, +) gobot.DigitalPinner { return newDigitalPinGpiod(chip, pin, o...) } diff --git a/system/digitalpin_access_test.go b/system/digitalpin_access_test.go index ef822a857..beda36d0c 100644 --- a/system/digitalpin_access_test.go +++ b/system/digitalpin_access_test.go @@ -3,7 +3,7 @@ package system import ( "testing" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) func Test_isSupportedSysfs(t *testing.T) { @@ -12,11 +12,11 @@ func Test_isSupportedSysfs(t *testing.T) { // act got := dpa.isSupported() // assert - gobottest.Assert(t, got, true) + assert.True(t, got) } func Test_isSupportedGpiod(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { mockPaths []string want bool }{ @@ -37,7 +37,7 @@ func Test_isSupportedGpiod(t *testing.T) { // act got := dpa.isSupported() // assert - gobottest.Assert(t, got, tc.want) + assert.Equal(t, tc.want, got) }) } } @@ -48,10 +48,10 @@ func Test_createAsSysfs(t *testing.T) { // act dp := dpa.createPin("chip", 8) // assert - gobottest.Refute(t, dp, nil) + assert.NotNil(t, dp) dps := dp.(*digitalPinSysfs) // chip is dropped - gobottest.Assert(t, dps.label, "gpio8") + assert.Equal(t, "gpio8", dps.label) } func Test_createAsGpiod(t *testing.T) { @@ -65,10 +65,10 @@ func Test_createAsGpiod(t *testing.T) { // act dp := dpa.createPin(chip, 18) // assert - gobottest.Refute(t, dp, nil) + assert.NotNil(t, dp) dpg := dp.(*digitalPinGpiod) - gobottest.Assert(t, dpg.label, label) - gobottest.Assert(t, dpg.chipName, chip) + assert.Equal(t, label, dpg.label) + assert.Equal(t, chip, dpg.chipName) } func Test_createPinWithOptionsSysfs(t *testing.T) { @@ -82,7 +82,7 @@ func Test_createPinWithOptionsSysfs(t *testing.T) { dp := dpa.createPin("", 9, WithPinLabel(label)) dps := dp.(*digitalPinSysfs) // assert - gobottest.Assert(t, dps.label, label) + assert.Equal(t, label, dps.label) } func Test_createPinWithOptionsGpiod(t *testing.T) { @@ -96,7 +96,7 @@ func Test_createPinWithOptionsGpiod(t *testing.T) { dp := dpa.createPin("", 19, WithPinLabel(label)) dpg := dp.(*digitalPinGpiod) // assert - gobottest.Assert(t, dpg.label, label) + assert.Equal(t, label, dpg.label) // test fallback for empty chip - gobottest.Assert(t, dpg.chipName, "gpiochip0") + assert.Equal(t, "gpiochip0", dpg.chipName) } diff --git a/system/digitalpin_bench_test.go b/system/digitalpin_bench_test.go index eb60722c6..c89a65c71 100644 --- a/system/digitalpin_bench_test.go +++ b/system/digitalpin_bench_test.go @@ -20,5 +20,4 @@ func BenchmarkDigitalRead(b *testing.B) { for i := 0; i < b.N; i++ { _, _ = pin.Read() } - } diff --git a/system/digitalpin_config.go b/system/digitalpin_config.go index c576eabd2..76e880283 100644 --- a/system/digitalpin_config.go +++ b/system/digitalpin_config.go @@ -53,6 +53,8 @@ type digitalPinConfig struct { debouncePeriod time.Duration edge int edgeEventHandler func(lineOffset int, timestamp time.Duration, detectedEdge string, seqno uint32, lseqno uint32) + pollInterval time.Duration + pollQuitChan chan struct{} } func newDigitalPinConfig(label string, options ...func(gobot.DigitalPinOptioner) bool) *digitalPinConfig { @@ -115,7 +117,8 @@ func WithPinDebounce(period time.Duration) func(gobot.DigitalPinOptioner) bool { // WithPinEventOnFallingEdge initializes the input pin for edge detection and call the event handler on falling edges. func WithPinEventOnFallingEdge(handler func(lineOffset int, timestamp time.Duration, detectedEdge string, seqno uint32, - lseqno uint32)) func(gobot.DigitalPinOptioner) bool { + lseqno uint32), +) func(gobot.DigitalPinOptioner) bool { return func(d gobot.DigitalPinOptioner) bool { return d.SetEventHandlerForEdge(handler, digitalPinEventOnFallingEdge) } @@ -123,7 +126,8 @@ func WithPinEventOnFallingEdge(handler func(lineOffset int, timestamp time.Durat // WithPinEventOnRisingEdge initializes the input pin for edge detection and call the event handler on rising edges. func WithPinEventOnRisingEdge(handler func(lineOffset int, timestamp time.Duration, detectedEdge string, seqno uint32, - lseqno uint32)) func(gobot.DigitalPinOptioner) bool { + lseqno uint32), +) func(gobot.DigitalPinOptioner) bool { return func(d gobot.DigitalPinOptioner) bool { return d.SetEventHandlerForEdge(handler, digitalPinEventOnRisingEdge) } @@ -131,12 +135,23 @@ func WithPinEventOnRisingEdge(handler func(lineOffset int, timestamp time.Durati // WithPinEventOnBothEdges initializes the input pin for edge detection and call the event handler on all edges. func WithPinEventOnBothEdges(handler func(lineOffset int, timestamp time.Duration, detectedEdge string, seqno uint32, - lseqno uint32)) func(gobot.DigitalPinOptioner) bool { + lseqno uint32), +) func(gobot.DigitalPinOptioner) bool { return func(d gobot.DigitalPinOptioner) bool { return d.SetEventHandlerForEdge(handler, digitalPinEventOnBothEdges) } } +// WithPinPollForEdgeDetection initializes a discrete input pin polling function to use for edge detection. +func WithPinPollForEdgeDetection( + pollInterval time.Duration, + pollQuitChan chan struct{}, +) func(gobot.DigitalPinOptioner) bool { + return func(d gobot.DigitalPinOptioner) bool { + return d.SetPollForEdgeDetection(pollInterval, pollQuitChan) + } +} + // SetLabel sets the label to use for next reconfigure. The function is intended to use by WithPinLabel(). func (d *digitalPinConfig) SetLabel(label string) bool { if d.label == label { @@ -208,9 +223,12 @@ func (d *digitalPinConfig) SetDebounce(period time.Duration) bool { return true } -// SetEventHandlerForEdge sets the input pin to edge detection and to call the event handler on specified edge. The +// SetEventHandlerForEdge sets the input pin to edge detection to call the event handler on specified edge. The // function is intended to use by WithPinEventOnFallingEdge(), WithPinEventOnRisingEdge() and WithPinEventOnBothEdges(). -func (d *digitalPinConfig) SetEventHandlerForEdge(handler func(int, time.Duration, string, uint32, uint32), edge int) bool { +func (d *digitalPinConfig) SetEventHandlerForEdge( + handler func(int, time.Duration, string, uint32, uint32), + edge int, +) bool { if d.edge == edge { return false } @@ -218,3 +236,21 @@ func (d *digitalPinConfig) SetEventHandlerForEdge(handler func(int, time.Duratio d.edgeEventHandler = handler return true } + +// SetPollForEdgeDetection use a discrete input polling method to detect edges. A poll interval of zero or smaller +// will deactivate this function. Please note: Using this feature is CPU consuming and less accurate than using cdev +// event handler (gpiod implementation) and should be done only if the former is not implemented or not working for +// the adaptor. E.g. sysfs driver in gobot has not implemented edge detection yet. The function is only useful +// together with SetEventHandlerForEdge() and its corresponding With*() functions. +// The function is intended to use by WithPinPollForEdgeDetection(). +func (d *digitalPinConfig) SetPollForEdgeDetection( + pollInterval time.Duration, + pollQuitChan chan struct{}, +) (changed bool) { + if d.pollInterval == pollInterval { + return false + } + d.pollInterval = pollInterval + d.pollQuitChan = pollQuitChan + return true +} diff --git a/system/digitalpin_config_test.go b/system/digitalpin_config_test.go index 961543837..c14d6fb5b 100644 --- a/system/digitalpin_config_test.go +++ b/system/digitalpin_config_test.go @@ -4,8 +4,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.DigitalPinOptioner = (*digitalPinConfig)(nil) @@ -18,10 +18,10 @@ func Test_newDigitalPinConfig(t *testing.T) { // act d := newDigitalPinConfig(label) // assert - gobottest.Refute(t, d, nil) - gobottest.Assert(t, d.label, label) - gobottest.Assert(t, d.direction, IN) - gobottest.Assert(t, d.outInitialState, 0) + assert.NotNil(t, d) + assert.Equal(t, label, d.label) + assert.Equal(t, IN, d.direction) + assert.Equal(t, 0, d.outInitialState) } func Test_newDigitalPinConfigWithOption(t *testing.T) { @@ -30,8 +30,8 @@ func Test_newDigitalPinConfigWithOption(t *testing.T) { // act d := newDigitalPinConfig("not used", WithPinLabel(label)) // assert - gobottest.Refute(t, d, nil) - gobottest.Assert(t, d.label, label) + assert.NotNil(t, d) + assert.Equal(t, label, d.label) } func TestWithPinLabel(t *testing.T) { @@ -39,7 +39,7 @@ func TestWithPinLabel(t *testing.T) { oldLabel = "old label" newLabel = "my optional label" ) - var tests = map[string]struct { + tests := map[string]struct { setLabel string want bool }{ @@ -58,8 +58,8 @@ func TestWithPinLabel(t *testing.T) { // act got := WithPinLabel(tc.setLabel)(dpc) // assert - gobottest.Assert(t, got, tc.want) - gobottest.Assert(t, dpc.label, tc.setLabel) + assert.Equal(t, tc.want, got) + assert.Equal(t, tc.setLabel, dpc.label) }) } } @@ -70,7 +70,7 @@ func TestWithPinDirectionOutput(t *testing.T) { oldVal = 3 newVal = 5 ) - var tests = map[string]struct { + tests := map[string]struct { oldDir string want bool wantVal int @@ -92,15 +92,15 @@ func TestWithPinDirectionOutput(t *testing.T) { // act got := WithPinDirectionOutput(newVal)(dpc) // assert - gobottest.Assert(t, got, tc.want) - gobottest.Assert(t, dpc.direction, "out") - gobottest.Assert(t, dpc.outInitialState, tc.wantVal) + assert.Equal(t, tc.want, got) + assert.Equal(t, "out", dpc.direction) + assert.Equal(t, tc.wantVal, dpc.outInitialState) }) } } func TestWithPinDirectionInput(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { oldDir string want bool }{ @@ -120,15 +120,15 @@ func TestWithPinDirectionInput(t *testing.T) { // act got := WithPinDirectionInput()(dpc) // assert - gobottest.Assert(t, got, tc.want) - gobottest.Assert(t, dpc.direction, "in") - gobottest.Assert(t, dpc.outInitialState, initValOut) + assert.Equal(t, tc.want, got) + assert.Equal(t, "in", dpc.direction) + assert.Equal(t, initValOut, dpc.outInitialState) }) } } func TestWithPinActiveLow(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { oldActiveLow bool want bool }{ @@ -147,14 +147,14 @@ func TestWithPinActiveLow(t *testing.T) { // act got := WithPinActiveLow()(dpc) // assert - gobottest.Assert(t, got, tc.want) - gobottest.Assert(t, dpc.activeLow, true) + assert.Equal(t, tc.want, got) + assert.True(t, dpc.activeLow) }) } } func TestWithPinPullDown(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { oldBias int want bool wantVal int @@ -174,14 +174,14 @@ func TestWithPinPullDown(t *testing.T) { // act got := WithPinPullDown()(dpc) // assert - gobottest.Assert(t, got, tc.want) - gobottest.Assert(t, dpc.bias, digitalPinBiasPullDown) + assert.Equal(t, tc.want, got) + assert.Equal(t, digitalPinBiasPullDown, dpc.bias) }) } } func TestWithPinPullUp(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { oldBias int want bool wantVal int @@ -201,14 +201,14 @@ func TestWithPinPullUp(t *testing.T) { // act got := WithPinPullUp()(dpc) // assert - gobottest.Assert(t, got, tc.want) - gobottest.Assert(t, dpc.bias, digitalPinBiasPullUp) + assert.Equal(t, tc.want, got) + assert.Equal(t, digitalPinBiasPullUp, dpc.bias) }) } } func TestWithPinOpenDrain(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { oldDrive int want bool wantVal int @@ -232,14 +232,14 @@ func TestWithPinOpenDrain(t *testing.T) { // act got := WithPinOpenDrain()(dpc) // assert - gobottest.Assert(t, got, tc.want) - gobottest.Assert(t, dpc.drive, digitalPinDriveOpenDrain) + assert.Equal(t, tc.want, got) + assert.Equal(t, digitalPinDriveOpenDrain, dpc.drive) }) } } func TestWithPinOpenSource(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { oldDrive int want bool wantVal int @@ -263,8 +263,8 @@ func TestWithPinOpenSource(t *testing.T) { // act got := WithPinOpenSource()(dpc) // assert - gobottest.Assert(t, got, tc.want) - gobottest.Assert(t, dpc.drive, digitalPinDriveOpenSource) + assert.Equal(t, tc.want, got) + assert.Equal(t, digitalPinDriveOpenSource, dpc.drive) }) } } @@ -274,7 +274,7 @@ func TestWithPinDebounce(t *testing.T) { oldVal = time.Duration(10) newVal = time.Duration(14) ) - var tests = map[string]struct { + tests := map[string]struct { oldDebouncePeriod time.Duration want bool wantVal time.Duration @@ -294,8 +294,8 @@ func TestWithPinDebounce(t *testing.T) { // act got := WithPinDebounce(newVal)(dpc) // assert - gobottest.Assert(t, got, tc.want) - gobottest.Assert(t, dpc.debouncePeriod, newVal) + assert.Equal(t, tc.want, got) + assert.Equal(t, newVal, dpc.debouncePeriod) }) } } @@ -305,13 +305,14 @@ func TestWithPinEventOnFallingEdge(t *testing.T) { oldVal = digitalPinEventNone newVal = digitalPinEventOnFallingEdge ) - var tests = map[string]struct { + tests := map[string]struct { oldEdge int want bool wantVal int }{ "no_change": { oldEdge: newVal, + want: false, }, "change": { oldEdge: oldVal, @@ -326,9 +327,13 @@ func TestWithPinEventOnFallingEdge(t *testing.T) { // act got := WithPinEventOnFallingEdge(handler)(dpc) // assert - gobottest.Assert(t, got, tc.want) - gobottest.Assert(t, dpc.edge, newVal) - gobottest.Refute(t, dpc.edgeEventHandler, nil) + assert.Equal(t, tc.want, got) + assert.Equal(t, newVal, dpc.edge) + if tc.want { + assert.NotNil(t, dpc.edgeEventHandler) + } else { + assert.Nil(t, dpc.edgeEventHandler) + } }) } } @@ -338,13 +343,14 @@ func TestWithPinEventOnRisingEdge(t *testing.T) { oldVal = digitalPinEventNone newVal = digitalPinEventOnRisingEdge ) - var tests = map[string]struct { + tests := map[string]struct { oldEdge int want bool wantVal int }{ "no_change": { oldEdge: newVal, + want: false, }, "change": { oldEdge: oldVal, @@ -359,9 +365,13 @@ func TestWithPinEventOnRisingEdge(t *testing.T) { // act got := WithPinEventOnRisingEdge(handler)(dpc) // assert - gobottest.Assert(t, got, tc.want) - gobottest.Assert(t, dpc.edge, newVal) - gobottest.Refute(t, dpc.edgeEventHandler, nil) + assert.Equal(t, tc.want, got) + assert.Equal(t, newVal, dpc.edge) + if tc.want { + assert.NotNil(t, dpc.edgeEventHandler) + } else { + assert.Nil(t, dpc.edgeEventHandler) + } }) } } @@ -371,13 +381,14 @@ func TestWithPinEventOnBothEdges(t *testing.T) { oldVal = digitalPinEventNone newVal = digitalPinEventOnBothEdges ) - var tests = map[string]struct { + tests := map[string]struct { oldEdge int want bool wantVal int }{ "no_change": { oldEdge: newVal, + want: false, }, "change": { oldEdge: oldVal, @@ -392,9 +403,46 @@ func TestWithPinEventOnBothEdges(t *testing.T) { // act got := WithPinEventOnBothEdges(handler)(dpc) // assert - gobottest.Assert(t, got, tc.want) - gobottest.Assert(t, dpc.edge, newVal) - gobottest.Refute(t, dpc.edgeEventHandler, nil) + assert.Equal(t, tc.want, got) + assert.Equal(t, newVal, dpc.edge) + if tc.want { + assert.NotNil(t, dpc.edgeEventHandler) + } else { + assert.Nil(t, dpc.edgeEventHandler) + } + }) + } +} + +func TestWithPinPollForEdgeDetection(t *testing.T) { + const ( + oldVal = time.Duration(1) + newVal = time.Duration(3) + ) + tests := map[string]struct { + oldPollInterval time.Duration + want bool + wantVal time.Duration + }{ + "no_change": { + oldPollInterval: newVal, + }, + "change": { + oldPollInterval: oldVal, + want: true, + }, + } + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + // arrange + dpc := &digitalPinConfig{pollInterval: tc.oldPollInterval} + stopChan := make(chan struct{}) + defer close(stopChan) + // act + got := WithPinPollForEdgeDetection(newVal, stopChan)(dpc) + // assert + assert.Equal(t, tc.want, got) + assert.Equal(t, newVal, dpc.pollInterval) }) } } diff --git a/system/digitalpin_gpiod.go b/system/digitalpin_gpiod.go index 1c5497b5e..c161dc00f 100644 --- a/system/digitalpin_gpiod.go +++ b/system/digitalpin_gpiod.go @@ -28,24 +28,36 @@ type digitalPinGpiod struct { var digitalPinGpiodReconfigure = digitalPinGpiodReconfigureLine // to allow unit testing -var digitalPinGpiodUsed = map[bool]string{true: "used", false: "unused"} -var digitalPinGpiodActiveLow = map[bool]string{true: "low", false: "high"} -var digitalPinGpiodDebounced = map[bool]string{true: "debounced", false: "not debounced"} +var ( + digitalPinGpiodUsed = map[bool]string{true: "used", false: "unused"} + digitalPinGpiodActiveLow = map[bool]string{true: "low", false: "high"} + digitalPinGpiodDebounced = map[bool]string{true: "debounced", false: "not debounced"} +) -var digitalPinGpiodDirection = map[gpiod.LineDirection]string{gpiod.LineDirectionUnknown: "unknown direction", - gpiod.LineDirectionInput: "input", gpiod.LineDirectionOutput: "output"} +var digitalPinGpiodDirection = map[gpiod.LineDirection]string{ + gpiod.LineDirectionUnknown: "unknown direction", + gpiod.LineDirectionInput: "input", gpiod.LineDirectionOutput: "output", +} -var digitalPinGpiodDrive = map[gpiod.LineDrive]string{gpiod.LineDrivePushPull: "push-pull", gpiod.LineDriveOpenDrain: "open-drain", - gpiod.LineDriveOpenSource: "open-source"} +var digitalPinGpiodDrive = map[gpiod.LineDrive]string{ + gpiod.LineDrivePushPull: "push-pull", gpiod.LineDriveOpenDrain: "open-drain", + gpiod.LineDriveOpenSource: "open-source", +} -var digitalPinGpiodBias = map[gpiod.LineBias]string{gpiod.LineBiasUnknown: "unknown", gpiod.LineBiasDisabled: "disabled", - gpiod.LineBiasPullUp: "pull-up", gpiod.LineBiasPullDown: "pull-down"} +var digitalPinGpiodBias = map[gpiod.LineBias]string{ + gpiod.LineBiasUnknown: "unknown", gpiod.LineBiasDisabled: "disabled", + gpiod.LineBiasPullUp: "pull-up", gpiod.LineBiasPullDown: "pull-down", +} -var digitalPinGpiodEdgeDetect = map[gpiod.LineEdge]string{gpiod.LineEdgeNone: "no", gpiod.LineEdgeRising: "rising", - gpiod.LineEdgeFalling: "falling", gpiod.LineEdgeBoth: "both"} +var digitalPinGpiodEdgeDetect = map[gpiod.LineEdge]string{ + gpiod.LineEdgeNone: "no", gpiod.LineEdgeRising: "rising", + gpiod.LineEdgeFalling: "falling", gpiod.LineEdgeBoth: "both", +} -var digitalPinGpiodEventClock = map[gpiod.LineEventClock]string{gpiod.LineEventClockMonotonic: "monotonic", - gpiod.LineEventClockRealtime: "realtime"} +var digitalPinGpiodEventClock = map[gpiod.LineEventClock]string{ + gpiod.LineEventClockMonotonic: "monotonic", + gpiod.LineEventClockRealtime: "realtime", +} // newDigitalPinGpiod returns a digital pin given the pin number, with the label "gobotio" followed by the pin number. // The pin label can be modified optionally. The pin is handled by the character device Kernel ABI. @@ -53,7 +65,7 @@ func newDigitalPinGpiod(chipName string, pin int, options ...func(gobot.DigitalP if chipName == "" { chipName = "gpiochip0" } - cfg := newDigitalPinConfig("gobotio"+strconv.Itoa(int(pin)), options...) + cfg := newDigitalPinConfig("gobotio"+strconv.Itoa(pin), options...) d := &digitalPinGpiod{ chipName: chipName, pin: pin, @@ -203,7 +215,8 @@ func digitalPinGpiodReconfigureLine(d *digitalPinGpiod, forceInput bool) error { opts = append(opts, gpiod.WithDebounce(d.debouncePeriod)) } // edge detection - if d.edgeEventHandler != nil { + if d.edgeEventHandler != nil && d.pollInterval <= 0 { + // use edge detection provided by gpiod wrappedHandler := digitalPinGpiodGetWrappedEventHandler(d.edgeEventHandler) switch d.edge { case digitalPinEventOnFallingEdge: @@ -218,7 +231,7 @@ func digitalPinGpiodReconfigureLine(d *digitalPinGpiod, forceInput bool) error { } } else { if systemGpiodDebug { - log.Printf("ouput (%s): ini-state %d, drive %d, inverse %t, bias %d", + log.Printf("output (%s): ini-state %d, drive %d, inverse %t, bias %d", id, d.outInitialState, d.drive, d.activeLow, d.bias) } opts = append(opts, gpiod.AsOutput(d.outInitialState)) @@ -265,10 +278,20 @@ func digitalPinGpiodReconfigureLine(d *digitalPinGpiod, forceInput bool) error { } d.line = gpiodLine + // start discrete polling function and wait for first read is done + if (d.direction == IN || forceInput) && d.pollInterval > 0 { + if err := startEdgePolling(d.label, d.Read, d.pollInterval, d.edge, d.edgeEventHandler, + d.pollQuitChan); err != nil { + return err + } + } + return nil } -func digitalPinGpiodGetWrappedEventHandler(handler func(int, time.Duration, string, uint32, uint32)) func(gpiod.LineEvent) { +func digitalPinGpiodGetWrappedEventHandler( + handler func(int, time.Duration, string, uint32, uint32), +) func(gpiod.LineEvent) { return func(evt gpiod.LineEvent) { detectedEdge := "none" switch evt.Type { diff --git a/system/digitalpin_gpiod_test.go b/system/digitalpin_gpiod_test.go index 6ed077469..30d7ba823 100644 --- a/system/digitalpin_gpiod_test.go +++ b/system/digitalpin_gpiod_test.go @@ -2,17 +2,18 @@ package system import ( "fmt" - "strings" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) -var _ gobot.DigitalPinner = (*digitalPinGpiod)(nil) -var _ gobot.DigitalPinValuer = (*digitalPinGpiod)(nil) -var _ gobot.DigitalPinOptioner = (*digitalPinGpiod)(nil) -var _ gobot.DigitalPinOptionApplier = (*digitalPinGpiod)(nil) +var ( + _ gobot.DigitalPinner = (*digitalPinGpiod)(nil) + _ gobot.DigitalPinValuer = (*digitalPinGpiod)(nil) + _ gobot.DigitalPinOptioner = (*digitalPinGpiod)(nil) + _ gobot.DigitalPinOptionApplier = (*digitalPinGpiod)(nil) +) func Test_newDigitalPinGpiod(t *testing.T) { // arrange @@ -24,12 +25,12 @@ func Test_newDigitalPinGpiod(t *testing.T) { // act d := newDigitalPinGpiod(chip, pin) // assert - gobottest.Refute(t, d, nil) - gobottest.Assert(t, d.chipName, chip) - gobottest.Assert(t, d.pin, pin) - gobottest.Assert(t, d.label, label) - gobottest.Assert(t, d.direction, IN) - gobottest.Assert(t, d.outInitialState, 0) + assert.NotNil(t, d) + assert.Equal(t, chip, d.chipName) + assert.Equal(t, pin, d.pin) + assert.Equal(t, label, d.label) + assert.Equal(t, IN, d.direction) + assert.Equal(t, 0, d.outInitialState) } func Test_newDigitalPinGpiodWithOptions(t *testing.T) { @@ -41,11 +42,11 @@ func Test_newDigitalPinGpiodWithOptions(t *testing.T) { // act dp := newDigitalPinGpiod("", 9, WithPinLabel(label)) // assert - gobottest.Assert(t, dp.label, label) + assert.Equal(t, label, dp.label) } func TestApplyOptions(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { changed []bool simErr error wantReconfigured int @@ -102,19 +103,19 @@ func TestApplyOptions(t *testing.T) { // act err := d.ApplyOptions(optionFunction1, optionFunction2) // assert - gobottest.Assert(t, err, tc.wantErr) - gobottest.Assert(t, d.digitalPinConfig.direction, "test") - gobottest.Assert(t, d.digitalPinConfig.drive, 15) - gobottest.Assert(t, reconfigured, tc.wantReconfigured) + assert.Equal(t, tc.wantErr, err) + assert.Equal(t, "test", d.digitalPinConfig.direction) + assert.Equal(t, 15, d.digitalPinConfig.drive) + assert.Equal(t, tc.wantReconfigured, reconfigured) if reconfigured > 0 { - gobottest.Assert(t, inputForced, false) + assert.False(t, inputForced) } }) } } -func TestExport(t *testing.T) { - var tests = map[string]struct { +func TestExportGpiod(t *testing.T) { + tests := map[string]struct { simErr error wantReconfigured int wantErr error @@ -147,15 +148,15 @@ func TestExport(t *testing.T) { // act err := d.Export() // assert - gobottest.Assert(t, err, tc.wantErr) - gobottest.Assert(t, inputForced, false) - gobottest.Assert(t, reconfigured, tc.wantReconfigured) + assert.Equal(t, tc.wantErr, err) + assert.False(t, inputForced) + assert.Equal(t, tc.wantReconfigured, reconfigured) }) } } -func TestUnexport(t *testing.T) { - var tests = map[string]struct { +func TestUnexportGpiod(t *testing.T) { + tests := map[string]struct { simNoLine bool simReconfErr error simCloseErr error @@ -207,17 +208,17 @@ func TestUnexport(t *testing.T) { // act err := dp.Unexport() // assert - gobottest.Assert(t, err, tc.wantErr) - gobottest.Assert(t, reconfigured, tc.wantReconfigured) + assert.Equal(t, tc.wantErr, err) + assert.Equal(t, tc.wantReconfigured, reconfigured) if reconfigured > 0 { - gobottest.Assert(t, inputForced, true) + assert.True(t, inputForced) } }) } } -func TestWrite(t *testing.T) { - var tests = map[string]struct { +func TestWriteGpiod(t *testing.T) { + tests := map[string]struct { val int simErr error want int @@ -255,18 +256,18 @@ func TestWrite(t *testing.T) { // assert if tc.wantErr != nil { for _, want := range tc.wantErr { - gobottest.Assert(t, strings.Contains(err.Error(), want), true) + assert.Contains(t, err.Error(), want) } } else { - gobottest.Assert(t, err, nil) + assert.NoError(t, err) } - gobottest.Assert(t, lm.lastVal, tc.want) + assert.Equal(t, tc.want, lm.lastVal) }) } } -func TestRead(t *testing.T) { - var tests = map[string]struct { +func TestReadGpiod(t *testing.T) { + tests := map[string]struct { simVal int simErr error wantErr []string @@ -290,12 +291,12 @@ func TestRead(t *testing.T) { // assert if tc.wantErr != nil { for _, want := range tc.wantErr { - gobottest.Assert(t, strings.Contains(err.Error(), want), true) + assert.Contains(t, err.Error(), want) } } else { - gobottest.Assert(t, err, nil) + assert.NoError(t, err) } - gobottest.Assert(t, tc.simVal, got) + assert.Equal(t, got, tc.simVal) }) } } diff --git a/system/digitalpin_mock.go b/system/digitalpin_mock.go index c2e8d2fd2..440df69ea 100644 --- a/system/digitalpin_mock.go +++ b/system/digitalpin_mock.go @@ -13,7 +13,8 @@ type digitalPinMock struct{} func (h *mockDigitalPinAccess) isSupported() bool { return true } func (h *mockDigitalPinAccess) createPin(chip string, pin int, - o ...func(gobot.DigitalPinOptioner) bool) gobot.DigitalPinner { + o ...func(gobot.DigitalPinOptioner) bool, +) gobot.DigitalPinner { dpm := &digitalPinMock{} return dpm } diff --git a/system/digitalpin_poll.go b/system/digitalpin_poll.go new file mode 100644 index 000000000..6526acfee --- /dev/null +++ b/system/digitalpin_poll.go @@ -0,0 +1,81 @@ +package system + +import ( + "fmt" + "sync" + "time" +) + +func startEdgePolling( + pinLabel string, + pinReadFunc func() (int, error), + pollInterval time.Duration, + wantedEdge int, + eventHandler func(offset int, t time.Duration, et string, sn uint32, lsn uint32), + quitChan chan struct{}, +) error { + if eventHandler == nil { + return fmt.Errorf("an event handler is mandatory for edge polling") + } + if quitChan == nil { + return fmt.Errorf("the quit channel is mandatory for edge polling") + } + + const allEdges = "all" + + triggerEventOn := "none" + switch wantedEdge { + case digitalPinEventOnFallingEdge: + triggerEventOn = DigitalPinEventFallingEdge + case digitalPinEventOnRisingEdge: + triggerEventOn = DigitalPinEventRisingEdge + case digitalPinEventOnBothEdges: + triggerEventOn = allEdges + default: + return fmt.Errorf("unsupported edge type %d for edge polling", wantedEdge) + } + + wg := sync.WaitGroup{} + wg.Add(1) + + go func() { + var oldState int + var readStart time.Time + var firstLoopDone bool + for { + select { + case <-quitChan: + return + default: + // note: pure reading takes between 30us and 1ms on rasperry Pi1, typically 50us, with sysfs also 500us + // can happen, so we use the time stamp before start of reading to reduce random duration offset + readStart = time.Now() + readValue, err := pinReadFunc() + if err != nil { + fmt.Printf("edge polling error occurred while reading the pin %s: %v", pinLabel, err) + readValue = oldState // keep the value + } + if readValue != oldState { + detectedEdge := DigitalPinEventRisingEdge + if readValue < oldState { + detectedEdge = DigitalPinEventFallingEdge + } + if firstLoopDone && (triggerEventOn == allEdges || triggerEventOn == detectedEdge) { + eventHandler(0, time.Duration(readStart.UnixNano()), detectedEdge, 0, 0) + } + oldState = readValue + } + // the real poll interval is increased by the reading time, see also note above + // negative or zero duration causes no sleep + time.Sleep(pollInterval - time.Since(readStart)) + if !firstLoopDone { + wg.Done() + firstLoopDone = true + } + } + } + }() + + wg.Wait() + return nil +} diff --git a/system/digitalpin_poll_test.go b/system/digitalpin_poll_test.go new file mode 100644 index 000000000..c9a9fd3d1 --- /dev/null +++ b/system/digitalpin_poll_test.go @@ -0,0 +1,175 @@ +package system + +import ( + "fmt" + "sync" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func Test_startEdgePolling(t *testing.T) { + type readValue struct { + value int + err string + } + tests := map[string]struct { + eventOnEdge int + simulateReadValues []readValue + simulateNoEventHandler bool + simulateNoQuitChan bool + wantEdgeTypes []string + wantErr string + }{ + "edge_falling": { + eventOnEdge: digitalPinEventOnFallingEdge, + simulateReadValues: []readValue{ + {value: 1}, + {value: 0}, + {value: 1}, + {value: 0}, + {value: 0}, + }, + wantEdgeTypes: []string{DigitalPinEventFallingEdge, DigitalPinEventFallingEdge}, + }, + "no_edge_falling": { + eventOnEdge: digitalPinEventOnFallingEdge, + simulateReadValues: []readValue{ + {value: 0}, + {value: 1}, + {value: 1}, + }, + wantEdgeTypes: nil, + }, + "edge_rising": { + eventOnEdge: digitalPinEventOnRisingEdge, + simulateReadValues: []readValue{ + {value: 0}, + {value: 1}, + {value: 0}, + {value: 1}, + {value: 1}, + }, + wantEdgeTypes: []string{DigitalPinEventRisingEdge, DigitalPinEventRisingEdge}, + }, + "no_edge_rising": { + eventOnEdge: digitalPinEventOnRisingEdge, + simulateReadValues: []readValue{ + {value: 1}, + {value: 0}, + {value: 0}, + }, + wantEdgeTypes: nil, + }, + "edge_both": { + eventOnEdge: digitalPinEventOnBothEdges, + simulateReadValues: []readValue{ + {value: 0}, + {value: 1}, + {value: 0}, + {value: 1}, + {value: 1}, + }, + wantEdgeTypes: []string{DigitalPinEventRisingEdge, DigitalPinEventFallingEdge, DigitalPinEventRisingEdge}, + }, + "no_edges_low": { + eventOnEdge: digitalPinEventOnBothEdges, + simulateReadValues: []readValue{ + {value: 0}, + {value: 0}, + {value: 0}, + }, + wantEdgeTypes: nil, + }, + "no_edges_high": { + eventOnEdge: digitalPinEventOnBothEdges, + simulateReadValues: []readValue{ + {value: 1}, + {value: 1}, + {value: 1}, + }, + wantEdgeTypes: nil, + }, + "read_error_keep_state": { + eventOnEdge: digitalPinEventOnBothEdges, + simulateReadValues: []readValue{ + {value: 0}, + {value: 1, err: "read error suppress rising and falling edge"}, + {value: 0}, + {value: 1}, + {value: 1}, + }, + wantEdgeTypes: []string{DigitalPinEventRisingEdge}, + }, + "error_no_eventhandler": { + simulateNoEventHandler: true, + wantErr: "event handler is mandatory", + }, + "error_no_quitchannel": { + simulateNoQuitChan: true, + wantErr: "quit channel is mandatory", + }, + "error_unsupported_edgetype_none": { + eventOnEdge: digitalPinEventNone, + wantErr: "unsupported edge type 0", + }, + } + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + // arrange + pinLabel := "test_pin" + pollInterval := time.Microsecond // zero is possible, just to show usage + // arrange event handler + var edgeTypes []string + var eventHandler func(int, time.Duration, string, uint32, uint32) + if !tc.simulateNoEventHandler { + eventHandler = func(offset int, t time.Duration, et string, sn uint32, lsn uint32) { + edgeTypes = append(edgeTypes, et) + } + } + // arrange quit channel + var quitChan chan struct{} + if !tc.simulateNoQuitChan { + quitChan = make(chan struct{}) + } + defer func() { + if quitChan != nil { + close(quitChan) + } + }() + // arrange reads + numCallsRead := 0 + wg := sync.WaitGroup{} + if tc.simulateReadValues != nil { + wg.Add(1) + } + readFunc := func() (int, error) { + numCallsRead++ + readVal := tc.simulateReadValues[numCallsRead-1] + var err error + if readVal.err != "" { + err = fmt.Errorf(readVal.err) + } + if numCallsRead >= len(tc.simulateReadValues) { + close(quitChan) // ensure no further read call + quitChan = nil // lets skip defer routine + wg.Done() // release assertions + } + + return readVal.value, err + } + // act + err := startEdgePolling(pinLabel, readFunc, pollInterval, tc.eventOnEdge, eventHandler, quitChan) + wg.Wait() + // assert + if tc.wantErr != "" { + assert.ErrorContains(t, err, tc.wantErr) + } else { + assert.NoError(t, err) + } + assert.Equal(t, len(tc.simulateReadValues), numCallsRead) + assert.Equal(t, tc.wantEdgeTypes, edgeTypes) + }) + } +} diff --git a/system/digitalpin_sysfs.go b/system/digitalpin_sysfs.go index b716ff639..7829befe4 100644 --- a/system/digitalpin_sysfs.go +++ b/system/digitalpin_sysfs.go @@ -47,7 +47,7 @@ func newDigitalPinSysfs(fs filesystem, pin string, options ...func(gobot.Digital func (d *digitalPinSysfs) ApplyOptions(options ...func(gobot.DigitalPinOptioner) bool) error { anyChange := false for _, option := range options { - anyChange = anyChange || option(d) + anyChange = option(d) || anyChange } if anyChange { return d.reconfigure() @@ -68,7 +68,7 @@ func (d *digitalPinSysfs) Export() error { // Unexport release the pin func (d *digitalPinSysfs) Unexport() error { - unexport, err := d.fs.openFile(gpioPath+"/unexport", os.O_WRONLY, 0644) + unexport, err := d.fs.openFile(gpioPath+"/unexport", os.O_WRONLY, 0o644) if err != nil { return err } @@ -87,7 +87,7 @@ func (d *digitalPinSysfs) Unexport() error { d.activeLowFile = nil } - _, err = writeFile(unexport, []byte(d.pin)) + err = writeFile(unexport, []byte(d.pin)) if err != nil { // If EINVAL then the pin is reserved in the system and can't be unexported e, ok := err.(*os.PathError) @@ -101,7 +101,7 @@ func (d *digitalPinSysfs) Unexport() error { // Write writes the given value to the character device func (d *digitalPinSysfs) Write(b int) error { - _, err := writeFile(d.valFile, []byte(strconv.Itoa(b))) + err := writeFile(d.valFile, []byte(strconv.Itoa(b))) return err } @@ -115,13 +115,13 @@ func (d *digitalPinSysfs) Read() (int, error) { } func (d *digitalPinSysfs) reconfigure() error { - exportFile, err := d.fs.openFile(gpioPath+"/export", os.O_WRONLY, 0644) + exportFile, err := d.fs.openFile(gpioPath+"/export", os.O_WRONLY, 0o644) if err != nil { return err } defer exportFile.Close() - _, err = writeFile(exportFile, []byte(d.pin)) + err = writeFile(exportFile, []byte(d.pin)) if err != nil { // If EBUSY then the pin has already been exported e, ok := err.(*os.PathError) @@ -137,12 +137,12 @@ func (d *digitalPinSysfs) reconfigure() error { attempt := 0 for { attempt++ - d.dirFile, err = d.fs.openFile(fmt.Sprintf("%s/%s/direction", gpioPath, d.label), os.O_RDWR, 0644) + d.dirFile, err = d.fs.openFile(fmt.Sprintf("%s/%s/direction", gpioPath, d.label), os.O_RDWR, 0o644) if err == nil { break } if attempt > 10 { - return err + break } time.Sleep(10 * time.Millisecond) } @@ -151,7 +151,7 @@ func (d *digitalPinSysfs) reconfigure() error { d.valFile.Close() } if err == nil { - d.valFile, err = d.fs.openFile(fmt.Sprintf("%s/%s/value", gpioPath, d.label), os.O_RDWR, 0644) + d.valFile, err = d.fs.openFile(fmt.Sprintf("%s/%s/value", gpioPath, d.label), os.O_RDWR, 0o644) } // configure direction @@ -162,47 +162,61 @@ func (d *digitalPinSysfs) reconfigure() error { // configure inverse logic if err == nil { if d.activeLow { - d.activeLowFile, err = d.fs.openFile(fmt.Sprintf("%s/%s/active_low", gpioPath, d.label), os.O_RDWR, 0644) + d.activeLowFile, err = d.fs.openFile(fmt.Sprintf("%s/%s/active_low", gpioPath, d.label), os.O_RDWR, 0o644) if err == nil { - _, err = writeFile(d.activeLowFile, []byte("1")) + err = writeFile(d.activeLowFile, []byte("1")) } } } - // configure bias (unsupported) + // configure bias (inputs and outputs, unsupported) if err == nil { if d.bias != digitalPinBiasDefault && systemSysfsDebug { log.Printf("bias options (%d) are not supported by sysfs, please use hardware resistors instead\n", d.bias) } } - // configure drive (unsupported) - if d.drive != digitalPinDrivePushPull && systemSysfsDebug { - log.Printf("drive options (%d) are not supported by sysfs\n", d.drive) - } + // configure debounce period (inputs only), edge detection (inputs only) and drive (outputs only) + if d.direction == IN { + // configure debounce (unsupported) + if d.debouncePeriod != 0 && systemSysfsDebug { + log.Printf("debounce period option (%d) is not supported by sysfs\n", d.debouncePeriod) + } - // configure debounce (unsupported) - if d.debouncePeriod != 0 && systemSysfsDebug { - log.Printf("debounce period option (%d) is not supported by sysfs\n", d.debouncePeriod) - } + // configure edge detection + if err == nil { + if d.edge != 0 && d.pollInterval <= 0 { + err = fmt.Errorf("edge detect option (%d) is not implemented for sysfs without discrete polling", d.edge) + } + } - // configure edge detection (not implemented) - if d.edge != 0 && systemSysfsDebug { - log.Printf("edge detect option (%d) is not implemented for sysfs\n", d.edge) + // start discrete polling function and wait for first read is done + if err == nil { + if d.pollInterval > 0 { + err = startEdgePolling(d.label, d.Read, d.pollInterval, d.edge, d.edgeEventHandler, d.pollQuitChan) + } + } + } else { + // configure drive (unsupported) + if d.drive != digitalPinDrivePushPull && systemSysfsDebug { + log.Printf("drive options (%d) are not supported by sysfs\n", d.drive) + } } if err != nil { - return d.Unexport() + if e := d.Unexport(); e != nil { + err = fmt.Errorf("unexport error '%v' after '%v'", e, err) + } } return err } func (d *digitalPinSysfs) writeDirectionWithInitialOutput() error { - if _, err := writeFile(d.dirFile, []byte(d.direction)); err != nil || d.direction == IN { + if err := writeFile(d.dirFile, []byte(d.direction)); err != nil || d.direction == IN { return err } - _, err := writeFile(d.valFile, []byte(strconv.Itoa(d.outInitialState))) + err := writeFile(d.valFile, []byte(strconv.Itoa(d.outInitialState))) return err } @@ -210,9 +224,9 @@ func (d *digitalPinSysfs) writeDirectionWithInitialOutput() error { // https://www.kernel.org/doc/Documentation/filesystems/sysfs.txt // https://www.kernel.org/doc/Documentation/gpio/sysfs.txt -var writeFile = func(f File, data []byte) (i int, err error) { +var writeFile = func(f File, data []byte) error { if f == nil { - return 0, errNotExported + return errNotExported } // sysfs docs say: @@ -221,8 +235,9 @@ var writeFile = func(f File, data []byte) (i int, err error) { // > entire buffer back. // however, this seems outdated/inaccurate (docs are from back in the Kernel BitKeeper days). - i, err = f.Write(data) - return i, err + // Write() returns already a non-nil error when n != len(b). + _, err := f.Write(data) + return err } var readFile = func(f File) ([]byte, error) { diff --git a/system/digitalpin_sysfs_test.go b/system/digitalpin_sysfs_test.go index 992a06be5..04b025ecd 100644 --- a/system/digitalpin_sysfs_test.go +++ b/system/digitalpin_sysfs_test.go @@ -4,122 +4,402 @@ import ( "errors" "os" "testing" + "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) -var _ gobot.DigitalPinner = (*digitalPinSysfs)(nil) -var _ gobot.DigitalPinValuer = (*digitalPinSysfs)(nil) -var _ gobot.DigitalPinOptioner = (*digitalPinSysfs)(nil) -var _ gobot.DigitalPinOptionApplier = (*digitalPinSysfs)(nil) +var ( + _ gobot.DigitalPinner = (*digitalPinSysfs)(nil) + _ gobot.DigitalPinValuer = (*digitalPinSysfs)(nil) + _ gobot.DigitalPinOptioner = (*digitalPinSysfs)(nil) + _ gobot.DigitalPinOptionApplier = (*digitalPinSysfs)(nil) +) -func initTestDigitalPinSysFsWithMockedFilesystem(mockPaths []string) (*digitalPinSysfs, *MockFilesystem) { +func initTestDigitalPinSysfsWithMockedFilesystem(mockPaths []string) (*digitalPinSysfs, *MockFilesystem) { fs := newMockFilesystem(mockPaths) pin := newDigitalPinSysfs(fs, "10") return pin, fs } -func TestDigitalPin(t *testing.T) { +func Test_newDigitalPinSysfs(t *testing.T) { + // arrange + m := &MockFilesystem{} + const pinID = "1" + // act + pin := newDigitalPinSysfs(m, pinID, WithPinOpenDrain()) + // assert + assert.Equal(t, pinID, pin.pin) + assert.Equal(t, m, pin.fs) + assert.Equal(t, "gpio"+pinID, pin.label) + assert.Equal(t, "in", pin.direction) + assert.Equal(t, 1, pin.drive) +} + +func TestApplyOptionsSysfs(t *testing.T) { + tests := map[string]struct { + changed []bool + simErr bool + wantExport string + wantErr string + }{ + "both_changed": { + changed: []bool{true, true}, + wantExport: "10", + }, + "first_changed": { + changed: []bool{true, false}, + wantExport: "10", + }, + "second_changed": { + changed: []bool{false, true}, + wantExport: "10", + }, + "none_changed": { + changed: []bool{false, false}, + wantExport: "", + }, + "error_on_change": { + changed: []bool{false, true}, + simErr: true, + wantExport: "10", + wantErr: "gpio10/direction: no such file", + }, + } + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + // arrange + mockPaths := []string{ + "/sys/class/gpio/export", + "/sys/class/gpio/gpio10/value", + } + if !tc.simErr { + mockPaths = append(mockPaths, "/sys/class/gpio/gpio10/direction") + } + pin, fs := initTestDigitalPinSysfsWithMockedFilesystem(mockPaths) + + optionFunction1 := func(gobot.DigitalPinOptioner) bool { + pin.digitalPinConfig.direction = OUT + return tc.changed[0] + } + optionFunction2 := func(gobot.DigitalPinOptioner) bool { + pin.digitalPinConfig.drive = 15 + return tc.changed[1] + } + // act + err := pin.ApplyOptions(optionFunction1, optionFunction2) + // assert + if tc.wantErr != "" { + assert.ErrorContains(t, err, tc.wantErr) + } else { + assert.NoError(t, err) + } + assert.Equal(t, OUT, pin.digitalPinConfig.direction) + assert.Equal(t, 15, pin.digitalPinConfig.drive) + // marker for call of reconfigure, correct reconfigure is tested independently + assert.Equal(t, tc.wantExport, fs.Files["/sys/class/gpio/export"].Contents) + }) + } +} + +func TestDirectionBehaviorSysfs(t *testing.T) { + // arrange + pin := newDigitalPinSysfs(nil, "1") + require.Equal(t, "in", pin.direction) + pin.direction = "test" + // act && assert + assert.Equal(t, "test", pin.DirectionBehavior()) +} + +func TestDigitalPinExportSysfs(t *testing.T) { + // this tests mainly the function reconfigure() + const ( + exportPath = "/sys/class/gpio/export" + dirPath = "/sys/class/gpio/gpio10/direction" + valuePath = "/sys/class/gpio/gpio10/value" + inversePath = "/sys/class/gpio/gpio10/active_low" + unexportPath = "/sys/class/gpio/unexport" + ) + allMockPaths := []string{exportPath, dirPath, valuePath, inversePath, unexportPath} + tests := map[string]struct { + mockPaths []string + changeDirection string + changeOutInitialState int + changeActiveLow bool + changeBias int + changeDrive int + changeDebouncePeriod time.Duration + changeEdge int + changePollInterval time.Duration + simEbusyOnWrite int + wantWrites int + wantExport string + wantUnexport string + wantDirection string + wantValue string + wantInverse string + wantErr string + }{ + "ok_without_option": { + mockPaths: allMockPaths, + wantWrites: 2, + wantExport: "10", + wantDirection: "in", + }, + "ok_input_bias_dropped": { + mockPaths: allMockPaths, + changeBias: 3, + wantWrites: 2, + wantExport: "10", + wantDirection: "in", + }, + "ok_input_drive_dropped": { + mockPaths: allMockPaths, + changeDrive: 2, + wantWrites: 2, + wantExport: "10", + wantDirection: "in", + }, + "ok_input_debounce_dropped": { + mockPaths: allMockPaths, + changeDebouncePeriod: 2 * time.Second, + wantWrites: 2, + wantExport: "10", + wantDirection: "in", + }, + "ok_input_inverse": { + mockPaths: allMockPaths, + changeActiveLow: true, + wantWrites: 3, + wantExport: "10", + wantDirection: "in", + wantInverse: "1", + }, + "ok_output": { + mockPaths: allMockPaths, + changeDirection: "out", + changeOutInitialState: 4, + wantWrites: 3, + wantExport: "10", + wantDirection: "out", + wantValue: "4", + }, + "ok_output_bias_dropped": { + mockPaths: allMockPaths, + changeDirection: "out", + changeBias: 3, + wantWrites: 3, + wantExport: "10", + wantDirection: "out", + wantValue: "0", + }, + "ok_output_drive_dropped": { + mockPaths: allMockPaths, + changeDirection: "out", + changeDrive: 2, + wantWrites: 3, + wantExport: "10", + wantDirection: "out", + wantValue: "0", + }, + "ok_output_debounce_dropped": { + mockPaths: allMockPaths, + changeDirection: "out", + changeDebouncePeriod: 2 * time.Second, + wantWrites: 3, + wantExport: "10", + wantDirection: "out", + wantValue: "0", + }, + "ok_output_inverse": { + mockPaths: allMockPaths, + changeDirection: "out", + changeActiveLow: true, + wantWrites: 4, + wantExport: "10", + wantDirection: "out", + wantInverse: "1", + wantValue: "0", + }, + "ok_already_exported": { + mockPaths: allMockPaths, + wantWrites: 2, + wantExport: "10", + wantDirection: "in", + simEbusyOnWrite: 1, // just means "already exported" + }, + "error_no_eventhandler_for_polling": { // this only tests the call of function, all other is tested separately + mockPaths: allMockPaths, + changePollInterval: 3 * time.Second, + wantWrites: 3, + wantUnexport: "10", + wantDirection: "in", + wantErr: "event handler is mandatory", + }, + "error_no_export_file": { + mockPaths: []string{unexportPath}, + wantErr: "/export: no such file", + }, + "error_no_direction_file": { + mockPaths: []string{exportPath, unexportPath}, + wantWrites: 2, + wantUnexport: "10", + wantErr: "gpio10/direction: no such file", + }, + "error_write_direction_file": { + mockPaths: allMockPaths, + wantWrites: 3, + wantUnexport: "10", + simEbusyOnWrite: 2, + wantErr: "device or resource busy", + }, + "error_no_value_file": { + mockPaths: []string{exportPath, dirPath, unexportPath}, + wantWrites: 2, + wantUnexport: "10", + wantErr: "gpio10/value: no such file", + }, + "error_no_inverse_file": { + mockPaths: []string{exportPath, dirPath, valuePath, unexportPath}, + changeActiveLow: true, + wantWrites: 3, + wantUnexport: "10", + wantErr: "gpio10/active_low: no such file", + }, + "error_input_edge_without_poll": { + mockPaths: allMockPaths, + changeEdge: 2, + wantWrites: 3, + wantUnexport: "10", + wantErr: "not implemented for sysfs without discrete polling", + }, + } + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + // arrange + fs := newMockFilesystem(tc.mockPaths) + pin := newDigitalPinSysfs(fs, "10") + if tc.changeDirection != "" { + pin.direction = tc.changeDirection + } + if tc.changeOutInitialState != 0 { + pin.outInitialState = tc.changeOutInitialState + } + if tc.changeActiveLow { + pin.activeLow = tc.changeActiveLow + } + if tc.changeBias != 0 { + pin.bias = tc.changeBias + } + if tc.changeDrive != 0 { + pin.drive = tc.changeDrive + } + if tc.changeDebouncePeriod != 0 { + pin.debouncePeriod = tc.changeDebouncePeriod + } + if tc.changeEdge != 0 { + pin.edge = tc.changeEdge + } + if tc.changePollInterval != 0 { + pin.pollInterval = tc.changePollInterval + } + // arrange write function + oldWriteFunc := writeFile + numCallsWrite := 0 + writeFile = func(f File, data []byte) error { + numCallsWrite++ + require.NoError(t, oldWriteFunc(f, data)) + if numCallsWrite == tc.simEbusyOnWrite { + return &os.PathError{Err: Syscall_EBUSY} + } + return nil + } + defer func() { writeFile = oldWriteFunc }() + // act + err := pin.Export() + // assert + if tc.wantErr != "" { + assert.ErrorContains(t, err, tc.wantErr) + } else { + assert.NoError(t, err) + assert.NotNil(t, pin.valFile) + assert.NotNil(t, pin.dirFile) + assert.Equal(t, tc.wantDirection, fs.Files[dirPath].Contents) + assert.Equal(t, tc.wantExport, fs.Files[exportPath].Contents) + assert.Equal(t, tc.wantValue, fs.Files[valuePath].Contents) + assert.Equal(t, tc.wantInverse, fs.Files[inversePath].Contents) + } + assert.Equal(t, tc.wantUnexport, fs.Files[unexportPath].Contents) + assert.Equal(t, tc.wantWrites, numCallsWrite) + }) + } +} + +func TestDigitalPinSysfs(t *testing.T) { mockPaths := []string{ "/sys/class/gpio/export", "/sys/class/gpio/unexport", "/sys/class/gpio/gpio10/value", "/sys/class/gpio/gpio10/direction", } - pin, fs := initTestDigitalPinSysFsWithMockedFilesystem(mockPaths) + pin, fs := initTestDigitalPinSysfsWithMockedFilesystem(mockPaths) - gobottest.Assert(t, pin.pin, "10") - gobottest.Assert(t, pin.label, "gpio10") - gobottest.Assert(t, pin.valFile, nil) + assert.Equal(t, "10", pin.pin) + assert.Equal(t, "gpio10", pin.label) + assert.Nil(t, pin.valFile) err := pin.Unexport() - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files["/sys/class/gpio/unexport"].Contents, "10") + assert.NoError(t, err) + assert.Equal(t, "10", fs.Files["/sys/class/gpio/unexport"].Contents) - err = pin.Export() - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files["/sys/class/gpio/export"].Contents, "10") - gobottest.Refute(t, pin.valFile, nil) + require.NoError(t, pin.Export()) err = pin.Write(1) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files["/sys/class/gpio/gpio10/value"].Contents, "1") + assert.NoError(t, err) + assert.Equal(t, "1", fs.Files["/sys/class/gpio/gpio10/value"].Contents) err = pin.ApplyOptions(WithPinDirectionInput()) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files["/sys/class/gpio/gpio10/direction"].Contents, "in") + assert.NoError(t, err) + assert.Equal(t, "in", fs.Files["/sys/class/gpio/gpio10/direction"].Contents) data, _ := pin.Read() - gobottest.Assert(t, 1, data) + assert.Equal(t, data, 1) pin2 := newDigitalPinSysfs(fs, "30") err = pin2.Write(1) - gobottest.Assert(t, err.Error(), "pin has not been exported") + assert.ErrorContains(t, err, "pin has not been exported") data, err = pin2.Read() - gobottest.Assert(t, err.Error(), "pin has not been exported") - gobottest.Assert(t, data, 0) + assert.ErrorContains(t, err, "pin has not been exported") + assert.Equal(t, 0, data) - writeFile = func(File, []byte) (int, error) { - return 0, &os.PathError{Err: Syscall_EINVAL} + writeFile = func(File, []byte) error { + return &os.PathError{Err: Syscall_EINVAL} } err = pin.Unexport() - gobottest.Assert(t, err, nil) + assert.NoError(t, err) - writeFile = func(File, []byte) (int, error) { - return 0, &os.PathError{Err: errors.New("write error")} + writeFile = func(File, []byte) error { + return &os.PathError{Err: errors.New("write error")} } err = pin.Unexport() - gobottest.Assert(t, err.(*os.PathError).Err, errors.New("write error")) - - // assert a busy error is dropped (just means "already exported") - cnt := 0 - writeFile = func(File, []byte) (int, error) { - cnt++ - if cnt == 1 { - return 0, &os.PathError{Err: Syscall_EBUSY} - } - return 0, nil - } - err = pin.Export() - gobottest.Assert(t, err, nil) - - // assert write error on export - writeFile = func(File, []byte) (int, error) { - return 0, &os.PathError{Err: errors.New("write error")} - } - err = pin.Export() - gobottest.Assert(t, err.(*os.PathError).Err, errors.New("write error")) -} - -func TestDigitalPinExportError(t *testing.T) { - mockPaths := []string{ - "/sys/class/gpio/export", - "/sys/class/gpio/gpio11/direction", - } - pin, _ := initTestDigitalPinSysFsWithMockedFilesystem(mockPaths) - - writeFile = func(File, []byte) (int, error) { - return 0, &os.PathError{Err: Syscall_EBUSY} - } - - err := pin.Export() - gobottest.Assert(t, err.Error(), " : /sys/class/gpio/gpio10/direction: no such file") + assert.ErrorContains(t, err.(*os.PathError).Err, "write error") } -func TestDigitalPinUnexportError(t *testing.T) { +func TestDigitalPinUnexportErrorSysfs(t *testing.T) { mockPaths := []string{ "/sys/class/gpio/unexport", } - pin, _ := initTestDigitalPinSysFsWithMockedFilesystem(mockPaths) + pin, _ := initTestDigitalPinSysfsWithMockedFilesystem(mockPaths) - writeFile = func(File, []byte) (int, error) { - return 0, &os.PathError{Err: Syscall_EBUSY} + writeFile = func(File, []byte) error { + return &os.PathError{Err: Syscall_EBUSY} } err := pin.Unexport() - gobottest.Assert(t, err.Error(), " : device or resource busy") + assert.ErrorContains(t, err, " : device or resource busy") } diff --git a/system/fs.go b/system/fs.go index ad7edccf3..2bdfd365d 100644 --- a/system/fs.go +++ b/system/fs.go @@ -35,7 +35,6 @@ func (fs *nativeFilesystem) find(baseDir string, pattern string) ([]string, erro for _, item := range items { if reg.MatchString(item.Name()) { found = append(found, path.Join(baseDir, item.Name())) - } } return found, nil diff --git a/system/fs_mock.go b/system/fs_mock.go index 197bad026..f7f1a5f1f 100644 --- a/system/fs_mock.go +++ b/system/fs_mock.go @@ -9,8 +9,10 @@ import ( "time" ) -var _ File = (*MockFile)(nil) -var _ filesystem = (*MockFilesystem)(nil) +var ( + _ File = (*MockFile)(nil) + _ filesystem = (*MockFilesystem)(nil) +) // MockFilesystem represents a filesystem of mock files. type MockFilesystem struct { diff --git a/system/fs_mock_test.go b/system/fs_mock_test.go index 78b974ad6..17296912d 100644 --- a/system/fs_mock_test.go +++ b/system/fs_mock_test.go @@ -4,48 +4,48 @@ import ( "sort" "testing" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) func TestMockFilesystemOpen(t *testing.T) { fs := newMockFilesystem([]string{"foo"}) f1 := fs.Files["foo"] - gobottest.Assert(t, f1.Opened, false) - f2, err := fs.openFile("foo", 0, 0666) - gobottest.Assert(t, f1, f2) - gobottest.Assert(t, err, nil) + assert.False(t, f1.Opened) + f2, err := fs.openFile("foo", 0, 0o666) + assert.Equal(t, f2, f1) + assert.NoError(t, err) err = f2.Sync() - gobottest.Assert(t, err, nil) + assert.NoError(t, err) - _, err = fs.openFile("bar", 0, 0666) - gobottest.Assert(t, err.Error(), " : bar: no such file") + _, err = fs.openFile("bar", 0, 0o666) + assert.ErrorContains(t, err, " : bar: no such file") fs.Add("bar") - f4, _ := fs.openFile("bar", 0, 0666) - gobottest.Refute(t, f4.Fd(), f1.Fd()) + f4, _ := fs.openFile("bar", 0, 0o666) + assert.NotEqual(t, f1.Fd(), f4.Fd()) } func TestMockFilesystemStat(t *testing.T) { fs := newMockFilesystem([]string{"foo", "bar/baz"}) fileStat, err := fs.stat("foo") - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fileStat.IsDir(), false) + assert.NoError(t, err) + assert.False(t, fileStat.IsDir()) dirStat, err := fs.stat("bar") - gobottest.Assert(t, err, nil) - gobottest.Assert(t, dirStat.IsDir(), true) + assert.NoError(t, err) + assert.True(t, dirStat.IsDir()) _, err = fs.stat("plonk") - gobottest.Assert(t, err.Error(), " : plonk: no such file") + assert.ErrorContains(t, err, " : plonk: no such file") } func TestMockFilesystemFind(t *testing.T) { // arrange fs := newMockFilesystem([]string{"/foo", "/bar/foo", "/bar/foo/baz", "/bar/baz/foo", "/bar/foo/bak"}) - var tests = map[string]struct { + tests := map[string]struct { baseDir string pattern string want []string @@ -61,9 +61,9 @@ func TestMockFilesystemFind(t *testing.T) { // act dirs, err := fs.find(tt.baseDir, tt.pattern) // assert - gobottest.Assert(t, err, nil) + assert.NoError(t, err) sort.Strings(dirs) - gobottest.Assert(t, dirs, tt.want) + assert.Equal(t, tt.want, dirs) }) } } @@ -72,15 +72,15 @@ func TestMockFilesystemWrite(t *testing.T) { fs := newMockFilesystem([]string{"bar"}) f1 := fs.Files["bar"] - f2, err := fs.openFile("bar", 0, 0666) - gobottest.Assert(t, err, nil) + f2, err := fs.openFile("bar", 0, 0o666) + assert.NoError(t, err) // Never been read or written. - gobottest.Assert(t, f1.Seq <= 0, true) + assert.True(t, f1.Seq <= 0) _, _ = f2.WriteString("testing") // Was written. - gobottest.Assert(t, f1.Seq > 0, true) - gobottest.Assert(t, f1.Contents, "testing") + assert.True(t, f1.Seq > 0) + assert.Equal(t, "testing", f1.Contents) } func TestMockFilesystemRead(t *testing.T) { @@ -88,19 +88,19 @@ func TestMockFilesystemRead(t *testing.T) { f1 := fs.Files["bar"] f1.Contents = "Yip" - f2, err := fs.openFile("bar", 0, 0666) - gobottest.Assert(t, err, nil) + f2, err := fs.openFile("bar", 0, 0o666) + assert.NoError(t, err) // Never been read or written. - gobottest.Assert(t, f1.Seq <= 0, true) + assert.True(t, f1.Seq <= 0) buffer := make([]byte, 20) n, _ := f2.Read(buffer) // Was read. - gobottest.Assert(t, f1.Seq > 0, true) - gobottest.Assert(t, n, 3) - gobottest.Assert(t, string(buffer[:3]), "Yip") + assert.True(t, f1.Seq > 0) + assert.Equal(t, 3, n) + assert.Equal(t, "Yip", string(buffer[:3])) n, _ = f2.ReadAt(buffer, 10) - gobottest.Assert(t, n, 3) + assert.Equal(t, 3, n) } diff --git a/system/fs_test.go b/system/fs_test.go index ebcbfd8bf..ae7d79113 100644 --- a/system/fs_test.go +++ b/system/fs_test.go @@ -4,19 +4,19 @@ import ( "os" "testing" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) func TestFilesystemOpen(t *testing.T) { fs := &nativeFilesystem{} - file, err := fs.openFile(os.DevNull, os.O_RDONLY, 0666) - gobottest.Assert(t, err, nil) + file, err := fs.openFile(os.DevNull, os.O_RDONLY, 0o666) + assert.NoError(t, err) var _ File = file } func TestFilesystemStat(t *testing.T) { fs := &nativeFilesystem{} fileInfo, err := fs.stat(os.DevNull) - gobottest.Assert(t, err, nil) - gobottest.Refute(t, fileInfo, nil) + assert.NoError(t, err) + assert.NotNil(t, fileInfo) } diff --git a/system/i2c_device.go b/system/i2c_device.go index 9b7717527..2c2e4cba1 100644 --- a/system/i2c_device.go +++ b/system/i2c_device.go @@ -189,7 +189,7 @@ func (d *i2cDevice) WriteByteData(address int, reg uint8, val uint8) error { return err } - var data = val + data := val return d.smbusAccess(address, I2C_SMBUS_WRITE, reg, I2C_SMBUS_BYTE_DATA, unsafe.Pointer(&data)) } @@ -202,7 +202,7 @@ func (d *i2cDevice) WriteWordData(address int, reg uint8, val uint16) error { return err } - var data = val + data := val return d.smbusAccess(address, I2C_SMBUS_WRITE, reg, I2C_SMBUS_WORD_DATA, unsafe.Pointer(&data)) } @@ -381,7 +381,7 @@ func (d *i2cDevice) syscallIoctl(signal uintptr, payload unsafe.Pointer, sender return nil } -func (d *i2cDevice) openFileLazy(sender string) (err error) { +func (d *i2cDevice) openFileLazy(sender string) (err error) { //nolint:unparam // useful for debugging // lazy initialization // note: "os.ModeExclusive" is undefined without create the file. This means for the existing character device, // a second open will not return an error e.g. due to a busy resource, so most likely "os.ModeExclusive" is not really diff --git a/system/i2c_device_test.go b/system/i2c_device_test.go index f40124d03..061bf395f 100644 --- a/system/i2c_device_test.go +++ b/system/i2c_device_test.go @@ -1,13 +1,12 @@ package system import ( - "errors" "os" "testing" "unsafe" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) const dev = "/dev/i2c-1" @@ -60,7 +59,7 @@ func initTestI2cDeviceWithMockedSys() (*i2cDevice, *mockSyscall) { } func TestNewI2cDevice(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { dev string wantErr string }{ @@ -80,11 +79,11 @@ func TestNewI2cDevice(t *testing.T) { d, err := a.NewI2cDevice(tc.dev) // assert if tc.wantErr != "" { - gobottest.Assert(t, err.Error(), tc.wantErr) - gobottest.Assert(t, d, (*i2cDevice)(nil)) + assert.ErrorContains(t, err, tc.wantErr) + assert.Equal(t, (*i2cDevice)(nil), d) } else { var _ gobot.I2cSystemDevicer = d - gobottest.Assert(t, err, nil) + assert.NoError(t, err) } }) } @@ -94,7 +93,7 @@ func TestClose(t *testing.T) { // arrange d, _ := initTestI2cDeviceWithMockedSys() // act & assert - gobottest.Assert(t, d.Close(), nil) + assert.NoError(t, d.Close()) } func TestWriteRead(t *testing.T) { @@ -106,15 +105,15 @@ func TestWriteRead(t *testing.T) { wn, werr := d.Write(1, wbuf) rn, rerr := d.Read(1, rbuf) // assert - gobottest.Assert(t, werr, nil) - gobottest.Assert(t, rerr, nil) - gobottest.Assert(t, wn, len(wbuf)) - gobottest.Assert(t, rn, len(wbuf)) // will read only the written values - gobottest.Assert(t, wbuf, rbuf[:len(wbuf)]) + assert.NoError(t, werr) + assert.NoError(t, rerr) + assert.Equal(t, len(wbuf), wn) + assert.Equal(t, len(wbuf), rn) // will read only the written values + assert.Equal(t, rbuf[:len(wbuf)], wbuf) } func TestReadByte(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { funcs uint64 syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err SyscallErrno) wantErr string @@ -143,22 +142,22 @@ func TestReadByte(t *testing.T) { got, err := d.ReadByte(2) // assert if tc.wantErr != "" { - gobottest.Assert(t, err.Error(), tc.wantErr) + assert.ErrorContains(t, err, tc.wantErr) } else { - gobottest.Assert(t, err, nil) - gobottest.Assert(t, got, want) - gobottest.Assert(t, msc.lastFile, d.file) - gobottest.Assert(t, msc.lastSignal, uintptr(I2C_SMBUS)) - gobottest.Assert(t, msc.smbus.readWrite, byte(I2C_SMBUS_READ)) - gobottest.Assert(t, msc.smbus.command, byte(0)) // register is set to 0 in that case - gobottest.Assert(t, msc.smbus.protocol, uint32(I2C_SMBUS_BYTE)) + assert.NoError(t, err) + assert.Equal(t, want, got) + assert.Equal(t, d.file, msc.lastFile) + assert.Equal(t, uintptr(I2C_SMBUS), msc.lastSignal) + assert.Equal(t, byte(I2C_SMBUS_READ), msc.smbus.readWrite) + assert.Equal(t, byte(0), msc.smbus.command) // register is set to 0 in that case + assert.Equal(t, uint32(I2C_SMBUS_BYTE), msc.smbus.protocol) } }) } } func TestReadByteData(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { funcs uint64 syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err SyscallErrno) wantErr string @@ -190,22 +189,22 @@ func TestReadByteData(t *testing.T) { got, err := d.ReadByteData(3, reg) // assert if tc.wantErr != "" { - gobottest.Assert(t, err.Error(), tc.wantErr) + assert.ErrorContains(t, err, tc.wantErr) } else { - gobottest.Assert(t, err, nil) - gobottest.Assert(t, got, want) - gobottest.Assert(t, msc.lastFile, d.file) - gobottest.Assert(t, msc.lastSignal, uintptr(I2C_SMBUS)) - gobottest.Assert(t, msc.smbus.readWrite, byte(I2C_SMBUS_READ)) - gobottest.Assert(t, msc.smbus.command, reg) - gobottest.Assert(t, msc.smbus.protocol, uint32(I2C_SMBUS_BYTE_DATA)) + assert.NoError(t, err) + assert.Equal(t, want, got) + assert.Equal(t, d.file, msc.lastFile) + assert.Equal(t, uintptr(I2C_SMBUS), msc.lastSignal) + assert.Equal(t, byte(I2C_SMBUS_READ), msc.smbus.readWrite) + assert.Equal(t, reg, msc.smbus.command) + assert.Equal(t, uint32(I2C_SMBUS_BYTE_DATA), msc.smbus.protocol) } }) } } func TestReadWordData(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { funcs uint64 syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err SyscallErrno) wantErr string @@ -240,15 +239,15 @@ func TestReadWordData(t *testing.T) { got, err := d.ReadWordData(4, reg) // assert if tc.wantErr != "" { - gobottest.Assert(t, err.Error(), tc.wantErr) + assert.ErrorContains(t, err, tc.wantErr) } else { - gobottest.Assert(t, err, nil) - gobottest.Assert(t, got, want) - gobottest.Assert(t, msc.lastFile, d.file) - gobottest.Assert(t, msc.lastSignal, uintptr(I2C_SMBUS)) - gobottest.Assert(t, msc.smbus.readWrite, byte(I2C_SMBUS_READ)) - gobottest.Assert(t, msc.smbus.command, reg) - gobottest.Assert(t, msc.smbus.protocol, uint32(I2C_SMBUS_WORD_DATA)) + assert.NoError(t, err) + assert.Equal(t, want, got) + assert.Equal(t, d.file, msc.lastFile) + assert.Equal(t, uintptr(I2C_SMBUS), msc.lastSignal) + assert.Equal(t, byte(I2C_SMBUS_READ), msc.smbus.readWrite) + assert.Equal(t, reg, msc.smbus.command) + assert.Equal(t, uint32(I2C_SMBUS_WORD_DATA), msc.smbus.protocol) } }) } @@ -269,7 +268,7 @@ func TestReadBlockData(t *testing.T) { wantB8 = byte(99) wantB9 = byte(111) ) - var tests = map[string]struct { + tests := map[string]struct { funcs uint64 syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err SyscallErrno) wantErr string @@ -298,23 +297,23 @@ func TestReadBlockData(t *testing.T) { err := d.ReadBlockData(5, reg, buf) // assert if tc.wantErr != "" { - gobottest.Assert(t, err.Error(), tc.wantErr) + assert.ErrorContains(t, err, tc.wantErr) } else { - gobottest.Assert(t, err, nil) - gobottest.Assert(t, buf, msc.dataSlice) - gobottest.Assert(t, msc.lastFile, d.file) - gobottest.Assert(t, msc.lastSignal, uintptr(I2C_SMBUS)) - gobottest.Assert(t, msc.sliceSize, uint8(len(buf)+1)) - gobottest.Assert(t, msc.smbus.readWrite, byte(I2C_SMBUS_READ)) - gobottest.Assert(t, msc.smbus.command, reg) - gobottest.Assert(t, msc.smbus.protocol, uint32(I2C_SMBUS_I2C_BLOCK_DATA)) + assert.NoError(t, err) + assert.Equal(t, msc.dataSlice, buf) + assert.Equal(t, d.file, msc.lastFile) + assert.Equal(t, uintptr(I2C_SMBUS), msc.lastSignal) + assert.Equal(t, uint8(len(buf)+1), msc.sliceSize) + assert.Equal(t, byte(I2C_SMBUS_READ), msc.smbus.readWrite) + assert.Equal(t, reg, msc.smbus.command) + assert.Equal(t, uint32(I2C_SMBUS_I2C_BLOCK_DATA), msc.smbus.protocol) } }) } } func TestWriteByte(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { funcs uint64 syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err SyscallErrno) wantErr string @@ -342,21 +341,21 @@ func TestWriteByte(t *testing.T) { err := d.WriteByte(6, val) // assert if tc.wantErr != "" { - gobottest.Assert(t, err.Error(), tc.wantErr) + assert.ErrorContains(t, err, tc.wantErr) } else { - gobottest.Assert(t, err, nil) - gobottest.Assert(t, msc.lastFile, d.file) - gobottest.Assert(t, msc.lastSignal, uintptr(I2C_SMBUS)) - gobottest.Assert(t, msc.smbus.readWrite, byte(I2C_SMBUS_WRITE)) - gobottest.Assert(t, msc.smbus.command, val) // in byte write, the register/command is used for the value - gobottest.Assert(t, msc.smbus.protocol, uint32(I2C_SMBUS_BYTE)) + assert.NoError(t, err) + assert.Equal(t, d.file, msc.lastFile) + assert.Equal(t, uintptr(I2C_SMBUS), msc.lastSignal) + assert.Equal(t, byte(I2C_SMBUS_WRITE), msc.smbus.readWrite) + assert.Equal(t, val, msc.smbus.command) // in byte write, the register/command is used for the value + assert.Equal(t, uint32(I2C_SMBUS_BYTE), msc.smbus.protocol) } }) } } func TestWriteByteData(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { funcs uint64 syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err SyscallErrno) wantErr string @@ -387,23 +386,23 @@ func TestWriteByteData(t *testing.T) { err := d.WriteByteData(7, reg, val) // assert if tc.wantErr != "" { - gobottest.Assert(t, err.Error(), tc.wantErr) + assert.ErrorContains(t, err, tc.wantErr) } else { - gobottest.Assert(t, err, nil) - gobottest.Assert(t, msc.lastFile, d.file) - gobottest.Assert(t, msc.lastSignal, uintptr(I2C_SMBUS)) - gobottest.Assert(t, msc.smbus.readWrite, byte(I2C_SMBUS_WRITE)) - gobottest.Assert(t, msc.smbus.command, reg) - gobottest.Assert(t, msc.smbus.protocol, uint32(I2C_SMBUS_BYTE_DATA)) - gobottest.Assert(t, len(msc.dataSlice), 1) - gobottest.Assert(t, msc.dataSlice[0], val) + assert.NoError(t, err) + assert.Equal(t, d.file, msc.lastFile) + assert.Equal(t, uintptr(I2C_SMBUS), msc.lastSignal) + assert.Equal(t, byte(I2C_SMBUS_WRITE), msc.smbus.readWrite) + assert.Equal(t, reg, msc.smbus.command) + assert.Equal(t, uint32(I2C_SMBUS_BYTE_DATA), msc.smbus.protocol) + assert.Equal(t, 1, len(msc.dataSlice)) + assert.Equal(t, val, msc.dataSlice[0]) } }) } } func TestWriteWordData(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { funcs uint64 syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err SyscallErrno) wantErr string @@ -436,18 +435,18 @@ func TestWriteWordData(t *testing.T) { err := d.WriteWordData(8, reg, val) // assert if tc.wantErr != "" { - gobottest.Assert(t, err.Error(), tc.wantErr) + assert.ErrorContains(t, err, tc.wantErr) } else { - gobottest.Assert(t, err, nil) - gobottest.Assert(t, msc.lastFile, d.file) - gobottest.Assert(t, msc.lastSignal, uintptr(I2C_SMBUS)) - gobottest.Assert(t, msc.smbus.readWrite, byte(I2C_SMBUS_WRITE)) - gobottest.Assert(t, msc.smbus.command, reg) - gobottest.Assert(t, msc.smbus.protocol, uint32(I2C_SMBUS_WORD_DATA)) - gobottest.Assert(t, len(msc.dataSlice), 2) + assert.NoError(t, err) + assert.Equal(t, d.file, msc.lastFile) + assert.Equal(t, uintptr(I2C_SMBUS), msc.lastSignal) + assert.Equal(t, byte(I2C_SMBUS_WRITE), msc.smbus.readWrite) + assert.Equal(t, reg, msc.smbus.command) + assert.Equal(t, uint32(I2C_SMBUS_WORD_DATA), msc.smbus.protocol) + assert.Equal(t, 2, len(msc.dataSlice)) // all common drivers write LSByte first - gobottest.Assert(t, msc.dataSlice[0], wantLSByte) - gobottest.Assert(t, msc.dataSlice[1], wantMSByte) + assert.Equal(t, wantLSByte, msc.dataSlice[0]) + assert.Equal(t, wantMSByte, msc.dataSlice[1]) } }) } @@ -468,7 +467,7 @@ func TestWriteBlockData(t *testing.T) { b8 = byte(0x88) b9 = byte(0x99) ) - var tests = map[string]struct { + tests := map[string]struct { funcs uint64 syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err SyscallErrno) wantErr string @@ -493,17 +492,17 @@ func TestWriteBlockData(t *testing.T) { err := d.WriteBlockData(9, reg, data) // assert if tc.wantErr != "" { - gobottest.Assert(t, err.Error(), tc.wantErr) + assert.ErrorContains(t, err, tc.wantErr) } else { - gobottest.Assert(t, err, nil) - gobottest.Assert(t, msc.lastFile, d.file) - gobottest.Assert(t, msc.lastSignal, uintptr(I2C_SMBUS)) - gobottest.Assert(t, msc.sliceSize, uint8(len(data)+1)) // including size element - gobottest.Assert(t, msc.smbus.readWrite, byte(I2C_SMBUS_WRITE)) - gobottest.Assert(t, msc.smbus.command, reg) - gobottest.Assert(t, msc.smbus.protocol, uint32(I2C_SMBUS_I2C_BLOCK_DATA)) - gobottest.Assert(t, msc.dataSlice[0], uint8(len(data))) // data size - gobottest.Assert(t, msc.dataSlice[1:], data) + assert.NoError(t, err) + assert.Equal(t, d.file, msc.lastFile) + assert.Equal(t, uintptr(I2C_SMBUS), msc.lastSignal) + assert.Equal(t, uint8(len(data)+1), msc.sliceSize) // including size element + assert.Equal(t, byte(I2C_SMBUS_WRITE), msc.smbus.readWrite) + assert.Equal(t, reg, msc.smbus.command) + assert.Equal(t, uint32(I2C_SMBUS_I2C_BLOCK_DATA), msc.smbus.protocol) + assert.Equal(t, uint8(len(data)), msc.dataSlice[0]) // data size + assert.Equal(t, data, msc.dataSlice[1:]) } }) } @@ -515,7 +514,7 @@ func TestWriteBlockDataTooMuch(t *testing.T) { // act err := d.WriteBlockData(10, 0x01, make([]byte, 33)) // assert - gobottest.Assert(t, err, errors.New("Writing blocks larger than 32 bytes (33) not supported")) + assert.ErrorContains(t, err, "Writing blocks larger than 32 bytes (33) not supported") } func Test_setAddress(t *testing.T) { @@ -524,12 +523,12 @@ func Test_setAddress(t *testing.T) { // act err := d.setAddress(0xff) // assert - gobottest.Assert(t, err, nil) - gobottest.Assert(t, msc.devAddress, uintptr(0xff)) + assert.NoError(t, err) + assert.Equal(t, uintptr(0xff), msc.devAddress) } func Test_queryFunctionality(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { requested uint64 dev string syscallImpl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err SyscallErrno) @@ -566,16 +565,16 @@ func Test_queryFunctionality(t *testing.T) { err := d.queryFunctionality(tc.requested, "test"+name) // assert if tc.wantErr != "" { - gobottest.Assert(t, err.Error(), tc.wantErr) + assert.ErrorContains(t, err, tc.wantErr) } else { - gobottest.Assert(t, err, nil) + assert.NoError(t, err) } if tc.wantFile { - gobottest.Refute(t, d.file, nil) + assert.NotNil(t, d.file) } else { - gobottest.Assert(t, d.file, (*MockFile)(nil)) + assert.Equal(t, (*MockFile)(nil), d.file) } - gobottest.Assert(t, d.funcs, tc.wantFuncs) + assert.Equal(t, tc.wantFuncs, d.funcs) }) } } diff --git a/system/pwmpin_sysfs.go b/system/pwmpin_sysfs.go index d695c6761..5950b7674 100644 --- a/system/pwmpin_sysfs.go +++ b/system/pwmpin_sysfs.go @@ -12,8 +12,8 @@ import ( const pwmDebug = false const ( - pwmPinErrorPattern = "%s() failed for id %s with %v" - pwmPinSetErrorPattern = "%s(%v) failed for id %s with %v" + pwmPinErrorPattern = "%s() failed for id %s with %v" //nolint:gosec // false positive + pwmPinSetErrorPattern = "%s(%v) failed for id %s with %v" //nolint:gosec // false positive ) // pwmPinSysFs represents a PWM pin @@ -221,7 +221,7 @@ func (p *pwmPinSysFs) pwmPolarityPath() string { } func writePwmFile(fs filesystem, path string, data []byte) (int, error) { - file, err := fs.openFile(path, os.O_WRONLY, 0644) + file, err := fs.openFile(path, os.O_WRONLY, 0o644) defer file.Close() //nolint:staticcheck // for historical reasons if err != nil { return 0, err @@ -231,7 +231,7 @@ func writePwmFile(fs filesystem, path string, data []byte) (int, error) { } func readPwmFile(fs filesystem, path string) ([]byte, error) { - file, err := fs.openFile(path, os.O_RDONLY, 0644) + file, err := fs.openFile(path, os.O_RDONLY, 0o644) defer file.Close() //nolint:staticcheck // for historical reasons if err != nil { return make([]byte, 0), err diff --git a/system/pwmpin_sysfs_test.go b/system/pwmpin_sysfs_test.go index 44c224973..63f458935 100644 --- a/system/pwmpin_sysfs_test.go +++ b/system/pwmpin_sysfs_test.go @@ -4,8 +4,8 @@ import ( "os" "testing" + "github.com/stretchr/testify/assert" "gobot.io/x/gobot/v2" - "gobot.io/x/gobot/v2/gobottest" ) var _ gobot.PWMPinner = (*pwmPinSysFs)(nil) @@ -32,45 +32,45 @@ func TestPwmPin(t *testing.T) { } pin, fs := initTestPWMPinSysFsWithMockedFilesystem(mockedPaths) - gobottest.Assert(t, pin.pin, "10") + assert.Equal(t, "10", pin.pin) err := pin.Unexport() - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/unexport"].Contents, "10") + assert.NoError(t, err) + assert.Equal(t, "10", fs.Files["/sys/class/pwm/pwmchip0/unexport"].Contents) err = pin.Export() - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/export"].Contents, "10") + assert.NoError(t, err) + assert.Equal(t, "10", fs.Files["/sys/class/pwm/pwmchip0/export"].Contents) - gobottest.Assert(t, pin.SetPolarity(false), nil) - gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm10/polarity"].Contents, inverted) + assert.NoError(t, pin.SetPolarity(false)) + assert.Equal(t, inverted, fs.Files["/sys/class/pwm/pwmchip0/pwm10/polarity"].Contents) pol, _ := pin.Polarity() - gobottest.Assert(t, pol, false) - gobottest.Assert(t, pin.SetPolarity(true), nil) - gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm10/polarity"].Contents, normal) + assert.False(t, pol) + assert.NoError(t, pin.SetPolarity(true)) + assert.Equal(t, normal, fs.Files["/sys/class/pwm/pwmchip0/pwm10/polarity"].Contents) pol, _ = pin.Polarity() - gobottest.Assert(t, pol, true) + assert.True(t, pol) - gobottest.Refute(t, fs.Files["/sys/class/pwm/pwmchip0/pwm10/enable"].Contents, "1") + assert.NotEqual(t, "1", fs.Files["/sys/class/pwm/pwmchip0/pwm10/enable"].Contents) err = pin.SetEnabled(true) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm10/enable"].Contents, "1") + assert.NoError(t, err) + assert.Equal(t, "1", fs.Files["/sys/class/pwm/pwmchip0/pwm10/enable"].Contents) err = pin.SetPolarity(true) - gobottest.Assert(t, err.Error(), "Cannot set PWM polarity when enabled") + assert.ErrorContains(t, err, "Cannot set PWM polarity when enabled") fs.Files["/sys/class/pwm/pwmchip0/pwm10/period"].Contents = "6" data, _ := pin.Period() - gobottest.Assert(t, data, uint32(6)) - gobottest.Assert(t, pin.SetPeriod(100000), nil) + assert.Equal(t, uint32(6), data) + assert.NoError(t, pin.SetPeriod(100000)) data, _ = pin.Period() - gobottest.Assert(t, data, uint32(100000)) + assert.Equal(t, uint32(100000), data) - gobottest.Refute(t, fs.Files["/sys/class/pwm/pwmchip0/pwm10/duty_cycle"].Contents, "1") + assert.NotEqual(t, "1", fs.Files["/sys/class/pwm/pwmchip0/pwm10/duty_cycle"].Contents) err = pin.SetDutyCycle(100) - gobottest.Assert(t, err, nil) - gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm10/duty_cycle"].Contents, "100") + assert.NoError(t, err) + assert.Equal(t, "100", fs.Files["/sys/class/pwm/pwmchip0/pwm10/duty_cycle"].Contents) data, _ = pin.DutyCycle() - gobottest.Assert(t, data, uint32(100)) + assert.Equal(t, uint32(100), data) } func TestPwmPinAlreadyExported(t *testing.T) { @@ -88,7 +88,7 @@ func TestPwmPinAlreadyExported(t *testing.T) { } // no error indicates that the pin was already exported - gobottest.Assert(t, pin.Export(), nil) + assert.NoError(t, pin.Export()) } func TestPwmPinExportError(t *testing.T) { @@ -107,7 +107,7 @@ func TestPwmPinExportError(t *testing.T) { // no error indicates that the pin was already exported err := pin.Export() - gobottest.Assert(t, err.Error(), "Export() failed for id 10 with : bad address") + assert.ErrorContains(t, err, "Export() failed for id 10 with : bad address") } func TestPwmPinUnxportError(t *testing.T) { @@ -125,7 +125,7 @@ func TestPwmPinUnxportError(t *testing.T) { } err := pin.Unexport() - gobottest.Assert(t, err.Error(), "Unexport() failed for id 10 with : device or resource busy") + assert.ErrorContains(t, err, "Unexport() failed for id 10 with : device or resource busy") } func TestPwmPinPeriodError(t *testing.T) { @@ -143,7 +143,7 @@ func TestPwmPinPeriodError(t *testing.T) { } _, err := pin.Period() - gobottest.Assert(t, err.Error(), "Period() failed for id 10 with : device or resource busy") + assert.ErrorContains(t, err, "Period() failed for id 10 with : device or resource busy") } func TestPwmPinPolarityError(t *testing.T) { @@ -161,7 +161,7 @@ func TestPwmPinPolarityError(t *testing.T) { } _, err := pin.Polarity() - gobottest.Assert(t, err.Error(), "Polarity() failed for id 10 with : device or resource busy") + assert.ErrorContains(t, err, "Polarity() failed for id 10 with : device or resource busy") } func TestPwmPinDutyCycleError(t *testing.T) { @@ -179,5 +179,5 @@ func TestPwmPinDutyCycleError(t *testing.T) { } _, err := pin.DutyCycle() - gobottest.Assert(t, err.Error(), "DutyCycle() failed for id 10 with : device or resource busy") + assert.ErrorContains(t, err, "DutyCycle() failed for id 10 with : device or resource busy") } diff --git a/system/spi_access_test.go b/system/spi_access_test.go index 6f087ae4c..e6f0266fc 100644 --- a/system/spi_access_test.go +++ b/system/spi_access_test.go @@ -3,7 +3,7 @@ package system import ( "testing" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) func TestGpioSpi_isSupported(t *testing.T) { @@ -12,11 +12,11 @@ func TestGpioSpi_isSupported(t *testing.T) { // act got := gsa.isSupported() // assert - gobottest.Assert(t, got, true) + assert.True(t, got) } func TestPeriphioSpi_isSupported(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { mockPaths []string want bool }{ @@ -37,7 +37,7 @@ func TestPeriphioSpi_isSupported(t *testing.T) { // act got := psa.isSupported() // assert - gobottest.Assert(t, got, tc.want) + assert.Equal(t, tc.want, got) }) } } diff --git a/system/syscall_mock.go b/system/syscall_mock.go index 8f00d0198..45317c97d 100644 --- a/system/syscall_mock.go +++ b/system/syscall_mock.go @@ -35,13 +35,13 @@ func (sys *mockSyscall) syscall(trap uintptr, f File, signal uintptr, payload un if sys.smbus.readWrite == I2C_SMBUS_WRITE { // get the data object payload as byte slice - sys.dataSlice = unsafe.Slice((*byte)(unsafe.Pointer(sys.smbus.data)), sys.sliceSize) + sys.dataSlice = unsafe.Slice((*byte)(sys.smbus.data), sys.sliceSize) } if sys.smbus.readWrite == I2C_SMBUS_READ { // fill data object with data from given slice to simulate reading if sys.dataSlice != nil { - slc := unsafe.Slice((*byte)(unsafe.Pointer(sys.smbus.data)), sys.sliceSize) + slc := unsafe.Slice((*byte)(sys.smbus.data), sys.sliceSize) if sys.smbus.protocol == I2C_SMBUS_BLOCK_DATA || sys.smbus.protocol == I2C_SMBUS_I2C_BLOCK_DATA { copy(slc[1:], sys.dataSlice) } else { @@ -54,7 +54,7 @@ func (sys *mockSyscall) syscall(trap uintptr, f File, signal uintptr, payload un // call mock implementation if sys.Impl != nil { - return sys.Impl(trap, f.Fd(), signal, uintptr(unsafe.Pointer(payload))) + return sys.Impl(trap, f.Fd(), signal, uintptr(payload)) } return 0, 0, 0 } @@ -69,6 +69,6 @@ func (sys *mockSyscall) retrieveSliceSize() uint8 { return 2 default: // for I2C_SMBUS_BLOCK_DATA, I2C_SMBUS_I2C_BLOCK_DATA - return *(*byte)(unsafe.Pointer(sys.smbus.data)) + 1 // first data element contains data size + return *(*byte)(sys.smbus.data) + 1 // first data element contains data size } } diff --git a/system/system.go b/system/system.go index 824d43865..708885265 100644 --- a/system/system.go +++ b/system/system.go @@ -113,7 +113,8 @@ func (a *Accesser) UseMockSpi() *MockSpiAccess { // NewDigitalPin returns a new system digital pin, according to the given pin number. func (a *Accesser) NewDigitalPin(chip string, pin int, - o ...func(gobot.DigitalPinOptioner) bool) gobot.DigitalPinner { + o ...func(gobot.DigitalPinOptioner) bool, +) gobot.DigitalPinner { return a.digitalPinAccess.createPin(chip, pin, o...) } diff --git a/system/system_options.go b/system/system_options.go index 302e4462e..049d888c7 100644 --- a/system/system_options.go +++ b/system/system_options.go @@ -40,7 +40,6 @@ func (a *Accesser) setDigitalPinToGpiodAccess() { if systemDebug { fmt.Println("gpiod driver not supported, fallback to sysfs") } - } func (a *Accesser) setSpiToGpioAccess(p gobot.DigitalPinnerProvider, sclkPin, nssPin, mosiPin, misoPin string) { diff --git a/system/system_test.go b/system/system_test.go index 54eb87486..83f1c46df 100644 --- a/system/system_test.go +++ b/system/system_test.go @@ -3,7 +3,7 @@ package system import ( "testing" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) func TestNewAccesser(t *testing.T) { @@ -13,10 +13,10 @@ func TestNewAccesser(t *testing.T) { nativeSys := a.sys.(*nativeSyscall) nativeFsSys := a.fs.(*nativeFilesystem) perphioSpi := a.spiAccess.(*periphioSpiAccess) - gobottest.Refute(t, a, nil) - gobottest.Refute(t, nativeSys, nil) - gobottest.Refute(t, nativeFsSys, nil) - gobottest.Refute(t, perphioSpi, nil) + assert.NotNil(t, a) + assert.NotNil(t, nativeSys) + assert.NotNil(t, nativeFsSys) + assert.NotNil(t, perphioSpi) } func TestNewAccesser_NewSpiDevice(t *testing.T) { @@ -34,17 +34,17 @@ func TestNewAccesser_NewSpiDevice(t *testing.T) { // act con, err := a.NewSpiDevice(busNum, chipNum, mode, bits, maxSpeed) // assert - gobottest.Assert(t, err, nil) - gobottest.Refute(t, con, nil) - gobottest.Assert(t, spi.busNum, busNum) - gobottest.Assert(t, spi.chipNum, chipNum) - gobottest.Assert(t, spi.mode, mode) - gobottest.Assert(t, spi.bits, bits) - gobottest.Assert(t, spi.maxSpeed, maxSpeed) + assert.NoError(t, err) + assert.NotNil(t, con) + assert.Equal(t, busNum, spi.busNum) + assert.Equal(t, chipNum, spi.chipNum) + assert.Equal(t, mode, spi.mode) + assert.Equal(t, bits, spi.bits) + assert.Equal(t, maxSpeed, spi.maxSpeed) } func TestNewAccesser_IsSysfsDigitalPinAccess(t *testing.T) { - var tests = map[string]struct { + tests := map[string]struct { gpiodAccesser bool wantSys bool }{ @@ -75,17 +75,17 @@ func TestNewAccesser_IsSysfsDigitalPinAccess(t *testing.T) { // act got := a.IsSysfsDigitalPinAccess() // assert - gobottest.Refute(t, a, nil) + assert.NotNil(t, a) if tc.wantSys { - gobottest.Assert(t, got, true) + assert.True(t, got) dpaSys := a.digitalPinAccess.(*sysfsDigitalPinAccess) - gobottest.Refute(t, dpaSys, nil) - gobottest.Assert(t, dpaSys.fs, a.fs.(*nativeFilesystem)) + assert.NotNil(t, dpaSys) + assert.Equal(t, a.fs.(*nativeFilesystem), dpaSys.fs) } else { - gobottest.Assert(t, got, false) + assert.False(t, got) dpaGpiod := a.digitalPinAccess.(*gpiodDigitalPinAccess) - gobottest.Refute(t, dpaGpiod, nil) - gobottest.Assert(t, dpaGpiod.fs, a.fs.(*nativeFilesystem)) + assert.NotNil(t, dpaGpiod) + assert.Equal(t, a.fs.(*nativeFilesystem), dpaGpiod.fs) } }) } diff --git a/utils_test.go b/utils_test.go index 383baa578..e07e299e6 100644 --- a/utils_test.go +++ b/utils_test.go @@ -1,11 +1,10 @@ package gobot import ( - "strings" "testing" "time" - "gobot.io/x/gobot/v2/gobottest" + "github.com/stretchr/testify/assert" ) func TestEvery(t *testing.T) { @@ -61,22 +60,22 @@ func TestAfter(t *testing.T) { t.Errorf("After was not called") } - gobottest.Assert(t, i, 1) + assert.Equal(t, 1, i) } func TestFromScale(t *testing.T) { - gobottest.Assert(t, FromScale(5, 0, 10), 0.5) + assert.Equal(t, 0.5, FromScale(5, 0, 10)) } func TestToScale(t *testing.T) { - gobottest.Assert(t, ToScale(500, 0, 10), 10.0) - gobottest.Assert(t, ToScale(-1, 0, 10), 0.0) - gobottest.Assert(t, ToScale(0.5, 0, 10), 5.0) + assert.Equal(t, 10.0, ToScale(500, 0, 10)) + assert.Equal(t, 0.0, ToScale(-1, 0, 10)) + assert.Equal(t, 5.0, ToScale(0.5, 0, 10)) } func TestRescale(t *testing.T) { - gobottest.Assert(t, Rescale(500, 0, 1000, 0, 10), 5.0) - gobottest.Assert(t, Rescale(-1.0, -1, 0, 490, 350), 490.0) + assert.Equal(t, 5.0, Rescale(500, 0, 1000, 0, 10)) + assert.Equal(t, 490.0, Rescale(-1.0, -1, 0, 490, 350)) } func TestRand(t *testing.T) { @@ -89,5 +88,5 @@ func TestRand(t *testing.T) { func TestDefaultName(t *testing.T) { name := DefaultName("tester") - gobottest.Assert(t, strings.Contains(name, "tester"), true) + assert.Contains(t, name, "tester") }