fix(wsl): spotify support

If we are in a WSL environment and tasklist.exe is in our PATH, leverage
it to scan for the Spotify.exe window title. Add unit tests and a new
mock for env.isWSL
This commit is contained in:
bewing 2021-10-11 02:02:51 -05:00 committed by GitHub
parent f64a8fa51a
commit b8d3f5781c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 104 additions and 9 deletions

View file

@ -7,7 +7,7 @@ sidebar_label: Spotify
## What
Show the currently playing song in the Spotify MacOS/Windows client.
On Windows, only the playing state is supported (no information when paused/stopped).
On Windows/WSL, only the playing state is supported (no information when paused/stopped).
On macOS, all states are supported (playing/paused/stopped).
**Be aware this can make the prompt a tad bit slower as it needs to get a response from the Spotify player.**

View file

@ -58,6 +58,7 @@ func TestGetGitOutputForCommand(t *testing.T) {
commandArgs := []string{"symbolic-ref", "--short", "HEAD"}
want := "je suis le output"
env := new(MockedEnvironment)
env.On("isWsl", nil).Return(false)
env.On("runCommand", "git", append(args, commandArgs...)).Return(want, nil)
env.On("getRuntimeGOOS", nil).Return("unix")
g := &git{
@ -92,6 +93,7 @@ type detachedContext struct {
func setupHEADContextEnv(context *detachedContext) *git {
env := new(MockedEnvironment)
env.On("isWsl", nil).Return(false)
env.On("hasFolder", "/rebase-merge").Return(context.rebaseMerge)
env.On("hasFolder", "/rebase-apply").Return(context.rebaseApply)
env.On("hasFolder", "/sequencer").Return(context.sequencer)
@ -530,6 +532,7 @@ func TestParseGitStatsInvalidLine(t *testing.T) {
func bootstrapUpstreamTest(upstream string) *git {
env := &MockedEnvironment{}
env.On("isWsl", nil).Return(false)
env.On("runCommand", "git", []string{"--no-optional-locks", "-c", "core.quotepath=false", "-c", "color.status=false", "remote", "get-url", "origin"}).Return(upstream, nil)
env.On("getRuntimeGOOS", nil).Return("unix")
props := &properties{

View file

@ -145,7 +145,8 @@ func (env *MockedEnvironment) stackCount() int {
}
func (env *MockedEnvironment) isWsl() bool {
return false
args := env.Called(nil)
return args.Bool(0)
}
func (env *MockedEnvironment) getTerminalWidth() (int, error) {

View file

@ -1,7 +0,0 @@
//go:build !darwin && !windows
package main
func (s *spotify) enabled() bool {
return false
}

View file

@ -0,0 +1,33 @@
//go:build !darwin && !windows
package main
import (
"encoding/csv"
"strings"
)
func (s *spotify) enabled() bool {
if !s.env.isWsl() {
return false
}
tlist, err := s.env.runCommand("tasklist.exe", "/V", "/FI", "Imagename eq Spotify.exe", "/FO", "CSV", "/NH")
if err != nil || strings.HasPrefix(tlist, "INFO") {
return false
}
records, err := csv.NewReader(strings.NewReader(tlist)).ReadAll()
if err != nil || len(records) == 0 {
return false
}
for _, record := range records {
title := record[len(record)-1]
if strings.Contains(title, " - ") {
infos := strings.Split(title, " - ")
s.artist = infos[0]
s.track = strings.Join(infos[1:], " - ")
s.status = "playing"
return true
}
}
return false
}

View file

@ -0,0 +1,65 @@
//go:build !darwin && !windows
package main
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
)
func TestSpotifyWsl(t *testing.T) {
cases := []struct {
Case string
ExpectedString string
ExpectedEnabled bool
ExecOutput string
}{
{
Case: "Spotify not running",
ExpectedString: " - ",
ExpectedEnabled: false,
ExecOutput: "INFO: No tasks are running which match the specified criteria.\n",
},
{
Case: "Spotify stopped/paused",
ExpectedString: " - ",
ExpectedEnabled: false,
ExecOutput: `"Spotify.exe","21824","Console","1","124,928 K","Running","PC\user","0:09:44","Spotify Premium"
"Spotify.exe","21876","Console","1","25,520 K","Running","PC\user","0:00:00","N/A"
"Spotify.exe","21988","Console","1","60,840 K","Not Responding","PC\user","0:04:56","AngleHiddenWindow"
"Spotify.exe","22052","Console","1","29,040 K","Unknown","PC\user","0:00:00","N/A"
"Spotify.exe","22072","Console","1","43,960 K","Unknown","PC\user","0:01:50","N/A"
"Spotify.exe","10404","Console","1","256,924 K","Unknown","PC\user","0:10:49","N/A"`,
},
{
Case: "Spotify playing",
ExpectedString: "\ue602 Candlemass - Spellbreaker",
ExpectedEnabled: true,
ExecOutput: `"Spotify.exe","21824","Console","1","124,928 K","Running","PC\user","0:09:44","Candlemass - Spellbreaker"
"Spotify.exe","21876","Console","1","25,520 K","Running","PC\user","0:00:00","N/A"
"Spotify.exe","21988","Console","1","60,840 K","Not Responding","PC\user","0:04:56","AngleHiddenWindow"
"Spotify.exe","22052","Console","1","29,040 K","Unknown","PC\user","0:00:00","N/A"
"Spotify.exe","22072","Console","1","43,960 K","Unknown","PC\user","0:01:50","N/A"
"Spotify.exe","10404","Console","1","256,924 K","Unknown","PC\user","0:10:49","N/A"`,
},
{
Case: "tasklist.exe not in path",
ExpectedString: " - ",
ExpectedEnabled: false,
ExecOutput: ""},
}
for _, tc := range cases {
env := new(MockedEnvironment)
env.On("isWsl", nil).Return(true)
env.On("runCommand", "tasklist.exe", []string{"/V", "/FI", "Imagename eq Spotify.exe", "/FO", "CSV", "/NH"}).Return(tc.ExecOutput, nil)
props := &properties{}
s := &spotify{
env: env,
props: props,
}
assert.Equal(t, tc.ExpectedEnabled, s.enabled(), fmt.Sprintf("Failed in case: %s", tc.Case))
assert.Equal(t, tc.ExpectedString, s.string(), fmt.Sprintf("Failed in case: %s", tc.Case))
}
}