Skip to content

Commit

Permalink
unit tests for server pkg
Browse files Browse the repository at this point in the history
  • Loading branch information
indiependente committed Nov 1, 2020
1 parent ef97ce8 commit 7aaa41b
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 33 deletions.
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,8 @@ coverage:
.PHONY: lint
lint:
golangci-lint run

.PHONY: test
test:
go test -race -cover ./...

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[![Go Report Card](https://goreportcard.com/badge/github.com/indiependente/autoEqMac)](https://goreportcard.com/report/github.com/indiependente/autoEqMac)
<a href='https://github.com/jpoles1/gopherbadger' target='_blank'>![gopherbadger-tag-do-not-edit](https://img.shields.io/badge/Go%20Coverage-72%25-brightgreen.svg?longCache=true&style=flat)</a>
<a href='https://github.com/jpoles1/gopherbadger' target='_blank'>![gopherbadger-tag-do-not-edit](https://img.shields.io/badge/Go%20Coverage-63%25-brightgreen.svg?longCache=true&style=flat)</a>
[![Workflow Status](https://github.com/indiependente/autoEqMac/workflows/lint-test/badge.svg)](https://github.com/indiependente/autoEqMac/actions)
# autoEqMac
An interactive CLI that retrieves headphones EQ data from the [AutoEq Project](https://github.com/jaakkopasanen/AutoEq) and produces a JSON preset ready to be imported into [EqMac](https://github.com/bitgapp/eqMac/).
Expand Down
13 changes: 13 additions & 0 deletions autoeq/mdparser.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ import (
"fmt"
)

const (
eqResultsPrefix = `https://raw.githubusercontent.com/jaakkopasanen/AutoEq/master/results`
fixedBandSuffix = `%20FixedBandEQ.txt`
)

// compile time interface implementation check
var _ MarkDownParser = MetadataParser{}

Expand All @@ -30,6 +35,14 @@ type MetadataParser struct {
FixedBandEQSuffix string
}

// NewMetadataParser returns a MetadataParser with populated fields.
func NewMetadataParser() MetadataParser {
return MetadataParser{
LinkPrefix: eqResultsPrefix,
FixedBandEQSuffix: fixedBandSuffix,
}
}

// ParseMetadata returns a slice of EQ metadata parsed from the input raw bytes.
// Returns an error if any.
func (p MetadataParser) ParseMetadata(data []byte) ([]EQMetadata, error) {
Expand Down
9 changes: 2 additions & 7 deletions autoeq/mdparser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@ import (
"github.com/stretchr/testify/require"
)

const (
autoEQResults = `https://raw.githubusercontent.com/jaakkopasanen/AutoEq/master/results`
fixedBandSuffix = `%20FixedBandEQ.txt`
)

func TestMetadataParser_ParseMetadata(t *testing.T) {
t.Parallel()
type fields struct {
Expand All @@ -33,7 +28,7 @@ func TestMetadataParser_ParseMetadata(t *testing.T) {
{
name: "Happy path",
fields: fields{
LinkPrefix: autoEQResults,
LinkPrefix: eqResultsPrefix,
FixedBandEQSuffix: fixedBandSuffix,
},
args: args{
Expand All @@ -44,7 +39,7 @@ func TestMetadataParser_ParseMetadata(t *testing.T) {
ID: "0",
Name: "1Custom SA02",
Author: "Crinacle",
Link: autoEQResults + "/crinacle/harman_in-ear_2019v2/1Custom%20SA02/1Custom%20SA02" + fixedBandSuffix,
Link: eqResultsPrefix + "/crinacle/harman_in-ear_2019v2/1Custom%20SA02/1Custom%20SA02" + fixedBandSuffix,
Global: 0,
},
},
Expand Down
32 changes: 14 additions & 18 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@ import (
"gopkg.in/alecthomas/kingpin.v2"
)

const (
autoEQResults = `https://raw.githubusercontent.com/jaakkopasanen/AutoEq/master/results`
fixedBandSuffix = `%20FixedBandEQ.txt`
)

var (
app = kingpin.New("autoEqMac", "EqMac preset generator powered by AutoEq.\n\nAn interactive CLI that retrieves headphones EQ data from the AutoEq project and produces a JSON preset ready to be imported into EqMac.")
file = app.Flag("file", "Output file path. By default it's the name of the headphones model selected.").Short('f').String()
Expand All @@ -38,10 +33,7 @@ func run() error {
kingpin.MustParse(app.Parse(os.Args[1:]))

client := http.DefaultClient
mdParser := autoeq.MetadataParser{
LinkPrefix: autoEQResults,
FixedBandEQSuffix: fixedBandSuffix,
}
mdParser := autoeq.NewMetadataParser()
eqGetter := autoeq.EQHTTPGetter{
Client: http.DefaultClient,
}
Expand Down Expand Up @@ -74,14 +66,7 @@ func run() error {
return fmt.Errorf("⛔️ could not find fixed band EQ preset: %w", err)
}

filename := *file
if filename == "" {
filename = strings.ReplaceAll(headphones, " ", "_") + ".json"
}
if !strings.HasSuffix(filename, ".json") {
filename += ".json"
}

filename := filename(file, headphones)
f, err := os.Create(filename)
if err != nil {
return fmt.Errorf("⛔️ could not create preset file: %w", err)
Expand All @@ -98,12 +83,23 @@ func run() error {
return nil
}

func filename(file *string, headphones string) string {
filename := *file
if filename == "" {
filename = fmt.Sprintf("%s.json", strings.ReplaceAll(headphones, " ", "_"))
}
if !strings.HasSuffix(filename, ".json") {
filename += ".json"
}
return filename
}

func populatedCompleter(eqMetas []autoeq.EQMetadata) func(prompt.Document) []prompt.Suggest {
return func(d prompt.Document) []prompt.Suggest {
var suggs []prompt.Suggest
for _, meta := range eqMetas {
suggs = append(suggs, prompt.Suggest{
Text: meta.Name, Description: meta.ID,
Text: meta.Name, Description: meta.Author,
})
}
return prompt.FilterContains(suggs, d.Text, true)
Expand Down
7 changes: 7 additions & 0 deletions server/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package server

import (
"io"
"net/http"

"github.com/indiependente/autoEqMac/autoeq"
"github.com/indiependente/autoEqMac/eqmac"
Expand All @@ -16,3 +17,9 @@ type Server interface {
GetEQMetadataByName(name string) (autoeq.EQMetadata, error)
WritePreset(w io.Writer, p eqmac.EQPreset) error
}

// Doer defines the behaviour of a component capable of doing an HTTP request,
// returning an HTTP response and an error.
type Doer interface {
Do(*http.Request) (*http.Response, error)
}
12 changes: 5 additions & 7 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,6 @@ func (e Error) Error() string {
return string(e)
}

// Doer defines the behaviour of a component capable of doing an HTTP request,
// returning an HTTP response and an error.
type Doer interface {
Do(*http.Request) (*http.Response, error)
}

// HTTPServer is an HTTP implementation of a Server.
// It fulfills the requests received by obtaining data via HTTP requests.
type HTTPServer struct {
Expand All @@ -60,7 +54,11 @@ func NewHTTPServer(d Doer, mdp autoeq.MarkDownParser, eqg autoeq.EQGetter, m map
// ListEQsMetadata returns a list of all the EQ metadata found by the server.
// Returns an error if any.
func (s HTTPServer) ListEQsMetadata() ([]autoeq.EQMetadata, error) {
resp, err := http.Get(headphonesIndex)
req, err := http.NewRequest(http.MethodGet, headphonesIndex, nil)
if err != nil {
return nil, fmt.Errorf("could not create HTTP request: %w", err)
}
resp, err := s.client.Do(req)
if err != nil {
return nil, fmt.Errorf("could not get updated headphones list: %w", err)
}
Expand Down
37 changes: 37 additions & 0 deletions server/server_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

157 changes: 157 additions & 0 deletions server/server_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
package server

import (
"bytes"
"io/ioutil"
"net/http"
"testing"

"github.com/golang/mock/gomock"
"github.com/google/uuid"
"github.com/indiependente/autoEqMac/autoeq"
"github.com/indiependente/autoEqMac/eqmac"
"github.com/indiependente/autoEqMac/eqmac/mapping"
"github.com/stretchr/testify/require"
)

var (
rawEqList = []byte(`# Index
This is a list of all equalization profiles. Target is in parentheses if there are results with multiple targets
from the same source.
- [Audio-Technica ATH-M50x](./oratory1990/harman_over-ear_2018/Audio-Technica%20ATH-M50x) by oratory1990
`)
rawEqData = []byte(`Filter 1: ON PK Fc 31 Hz Gain 5.8 dB Q 1.41`)
rawGlobalData = []byte(`# Audio-Technica ATH-M50x
See [usage instructions](https://github.com/jaakkopasanen/AutoEq#usage) for more options and info.
### Parametric EQs
In case of using parametric equalizer, apply preamp of **-7.0dB** and build filters manually
with these parameters. The first 5 filters can be used independently.
When using independent subset of filters, apply preamp of **-7.0dB**.
| Type | Fc | Q | Gain |
|:--------|:---------|:-----|:--------|
| Peaking | 23 Hz | 0.95 | 6.3 dB |
| Peaking | 327 Hz | 2.37 | 3.2 dB |
| Peaking | 5826 Hz | 5.21 | 6.7 dB |
| Peaking | 18679 Hz | 0.06 | -2.4 dB |
| Peaking | 19122 Hz | 0.41 | -9.3 dB |
| Peaking | 167 Hz | 2.59 | -2.0 dB |
| Peaking | 1397 Hz | 0.62 | 1.2 dB |
| Peaking | 2608 Hz | 3.12 | -2.3 dB |
| Peaking | 7966 Hz | 2.55 | -2.1 dB |
| Peaking | 9166 Hz | 3.3 | 3.4 dB |
### Fixed Band EQs
In case of using fixed band (also called graphic) equalizer, apply preamp of **-6.4dB**
(if available) and set gains manually with these parameters.
| Type | Fc | Q | Gain |
|:--------|:---------|:-----|:---------|
| Peaking | 31 Hz | 1.41 | 5.8 dB |
| Peaking | 62 Hz | 1.41 | 0.9 dB |
| Peaking | 125 Hz | 1.41 | -1.7 dB |
| Peaking | 250 Hz | 1.41 | 1.7 dB |
| Peaking | 500 Hz | 1.41 | 0.9 dB |
| Peaking | 1000 Hz | 1.41 | 0.9 dB |
| Peaking | 2000 Hz | 1.41 | -0.7 dB |
| Peaking | 4000 Hz | 1.41 | -0.8 dB |
| Peaking | 8000 Hz | 1.41 | -0.6 dB |
| Peaking | 16000 Hz | 1.41 | -13.5 dB |
### Graphs
![](./Audio-Technica%20ATH-M50x.png)`)
id = uuid.New().String()
eqMeta = autoeq.EQMetadata{
ID: "0",
Name: "Audio-Technica ATH-M50x",
Author: "oratory1990",
Link: "https://raw.githubusercontent.com/jaakkopasanen/AutoEq/master/results/oratory1990/harman_over-ear_2018/Audio-Technica%20ATH-M50x/Audio-Technica%20ATH-M50x%20FixedBandEQ.txt",
Global: 0,
}
eqPreset = eqmac.EQPreset{
Gains: eqmac.Gains{
Global: -6.4,
Bands: []float64{5.8},
},
ID: id,
IsDefault: false,
Name: "Audio-Technica ATH-M50x",
}
)

func TestHTTPServer(t *testing.T) {
t.Parallel()

tests := []struct {
name string
setupExpectations func(doer *MockDoer)
want struct {
meta []autoeq.EQMetadata
preset eqmac.EQPreset
}
wantErr bool
}{
{
name: "Happy path",
setupExpectations: func(doer *MockDoer) {
doer.EXPECT().Do(gomock.Any()).Return(&http.Response{
StatusCode: http.StatusOK,
Body: ioutil.NopCloser(bytes.NewReader(rawEqList)),
}, nil)
doer.EXPECT().Do(gomock.Any()).Return(&http.Response{
StatusCode: http.StatusOK,
Body: ioutil.NopCloser(bytes.NewReader(rawEqData)),
}, nil)
doer.EXPECT().Do(gomock.Any()).Return(&http.Response{
StatusCode: http.StatusOK,
Body: ioutil.NopCloser(bytes.NewReader(rawGlobalData)),
}, nil)
},
want: struct {
meta []autoeq.EQMetadata
preset eqmac.EQPreset
}{
meta: []autoeq.EQMetadata{
eqMeta,
},
preset: eqPreset,
},

wantErr: false,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
doer := NewMockDoer(ctrl)
mdp := autoeq.NewMetadataParser()
eqg := autoeq.EQHTTPGetter{Client: doer}
mapp := mapping.NewAutoEQMapper(mapping.WrappedGenerator(func() string {
return id
}))
tt.setupExpectations(doer)

s := HTTPServer{
client: doer,
mdparser: mdp,
eqGetter: eqg,
mapper: mapp,
eqMetas: map[string]autoeq.EQMetadata{},
eqNameID: map[string]string{},
}
got, err := s.ListEQsMetadata()
require.NoError(t, err)
require.Equal(t, tt.want.meta, got)
gotMeta, err := s.GetEQMetadataByName(eqMeta.Name)
require.Equal(t, tt.want.meta[0], gotMeta)
gotPreset, err := s.GetFixedBandEQPreset(eqMeta.ID)
require.Equal(t, tt.want.preset, gotPreset)
err = s.WritePreset(ioutil.Discard, gotPreset)
require.NoError(t, err)
})
}
}

0 comments on commit 7aaa41b

Please sign in to comment.