diff --git a/api/endpoints.go b/api/endpoints.go index f80b20c2610836526edd1e1a660b112134510c40..b0008deca3c29c04561d53f77f36a473fb1b9506 100644 --- a/api/endpoints.go +++ b/api/endpoints.go @@ -178,13 +178,13 @@ type GetIndexResponseObject interface { VisitGetIndexResponse(w http.ResponseWriter) error } -type GetIndex200TexthtmlResponse struct { +type GetIndex200TexthtmlCharsetUtf8Response struct { Body io.Reader ContentLength int64 } -func (response GetIndex200TexthtmlResponse) VisitGetIndexResponse(w http.ResponseWriter) error { - w.Header().Set("Content-Type", "text/html") +func (response GetIndex200TexthtmlCharsetUtf8Response) VisitGetIndexResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "text/html; charset=utf-8") if response.ContentLength != 0 { w.Header().Set("Content-Length", fmt.Sprint(response.ContentLength)) } @@ -260,12 +260,12 @@ func (sh *strictHandler) GetIndex(w http.ResponseWriter, r *http.Request) { // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "H4sIAAAAAAAC/2RRTW/cIBD9K+idkdm2N07tqVq1VasmufVC8KyNagYEYzdW5P9eQTbSSntBMPPmfQyv", - "CHxJsK/wicV5aVeKLiyw+Etb4M/LProhEDTYRYLFt1ZW3/fRQWMtDTmL5GqNecceGiNVX0KWkBgWjzOp", - "lYNU9Y+e1dN5gMYSPHGlpnhl/nF+vKNMmbimtXgaUpnMdcjEIE1FqMT68/JAZQuebsamIMPVjek5TJeH", - "hgRZGvKp2/GJNypCBRoblfpm98NwGk6Nv6m7HGDxqZc0spO5Ns+mHRP1jd2HfXaVVHYTqUsqSmZSD7++", - "DH8YnbO4Bj2PsPhKcuaRXqBRqObElTr9x9Pp/VuIu4jQi5hZ4tIe1c8UXS/vucWpUgJPOI673UcXuFtB", - "69U1Rld2WPwmWQtXdds/jv8BAAD//xuhfPkSAgAA", + "H4sIAAAAAAAC/2RRTYvUQBD9K807x2TUi0QEPcmgori7Ny+9nZqkMV0dqirjhiX/Xbp3FgbmEkK9V++j", + "6xmRTxn9M0Jm88HKLyUfZ/T4S+fIn+dt8G0kNGCfCD2+lbH7vg0eDVYpzMls0b7rXrl7g4E0SFwsZkaP", + "+4ncytHU/aNH93Bs0WCOgVipOF6UfxzvbyTzQqx5lUBtlrG7LHUpWnExkqQ/T3ck5xjoam2M1l7SdLVH", + "V+3RwKLNhflQ44TMZxIjQYMzib7Efdse2kPRL+5+iejxvo4aLN4mLZm78hmpvtht2Uev5BY/kjtlcTaR", + "u/v1pf3DqJriC/U4oMdXsiMP9IQGQrpkVqry7w6H17MQVxOjJ+smS/NHFyYvSvZptdObDwXTMFHylbUt", + "pZ2aRB6x7zenSD5yTYaC6ZqSlw09fpOtwuqu8X3/HwAA//9j+EgjIQIAAA==", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/api/implementation.go b/api/implementation.go index fa849e16eadc47135a55ac0748e189f95cefddfb..7461c68c9b8ed13f2bafe741e16c8f5af3d3676e 100644 --- a/api/implementation.go +++ b/api/implementation.go @@ -20,7 +20,7 @@ func (ua UnitsAPI) GetIndex(_ context.Context, _ GetIndexRequestObject) (GetInde <h1 x-data="{ message: 'I ❤️ Alpine' }" x-text="message"></h1> </body> </html>` - response := GetIndex200TexthtmlResponse{ + response := GetIndex200TexthtmlCharsetUtf8Response{ Body: strings.NewReader(body), ContentLength: int64(len(body)), } diff --git a/api/units.yaml b/api/units.yaml index 1b0f6a99c3cbd22e07569297f0fa3df1126dcc1e..80d925bbd6cf85462b4417581428166a5874d825 100644 --- a/api/units.yaml +++ b/api/units.yaml @@ -27,6 +27,6 @@ paths: '200': description: main page content: - text/html: + text/html; charset=utf-8: schema: type: string diff --git a/go.mod b/go.mod index 7e8ed8568d035aa87c845e8a19697ecd53938101..0eb6a4b44a3251451d7d59019238d90f84c0b339 100644 --- a/go.mod +++ b/go.mod @@ -3,13 +3,18 @@ module git.lyda.ie/kevin/units go 1.22.2 require ( + github.com/getkin/kin-openapi v0.124.0 + github.com/ichiban/prolog v1.2.0 + github.com/oapi-codegen/nethttp-middleware v1.0.2 + github.com/oapi-codegen/runtime v1.1.1 github.com/spf13/cobra v1.8.0 github.com/spf13/viper v1.19.0 + github.com/stretchr/testify v1.9.0 ) require ( + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/getkin/kin-openapi v0.124.0 // indirect github.com/go-openapi/jsonpointer v0.20.2 // indirect github.com/go-openapi/swag v0.22.8 // indirect github.com/gorilla/mux v1.8.1 // indirect @@ -17,18 +22,13 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/invopop/yaml v0.2.0 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/labstack/echo/v4 v4.12.0 // indirect - github.com/labstack/gommon v0.4.2 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oapi-codegen/nethttp-middleware v1.0.2 // indirect - github.com/oapi-codegen/runtime v1.1.1 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect @@ -36,13 +36,9 @@ require ( github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.6.0 // indirect - github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasttemplate v1.2.2 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect - golang.org/x/crypto v0.22.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/net v0.24.0 // indirect golang.org/x/sys v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index a71f3670ff3ce7f3e06552b2eba82070cfdc50ce..b3a74f1b97ed499f43bc32a3cf6128cd855a104f 100644 --- a/go.sum +++ b/go.sum @@ -13,12 +13,16 @@ github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbX github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= github.com/go-openapi/swag v0.22.8 h1:/9RjDSQ0vbFR+NyjGMkFTsA1IA0fmhKSThmfGZjicbw= github.com/go-openapi/swag v0.22.8/go.mod h1:6QT22icPLEqAM/z/TChgb4WAveCHF92+2gF0CNjHpPI= +github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= +github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/ichiban/prolog v1.2.0 h1:DrwolRMxdzI3126nCSpyxJtK4OVVqmbu7XpGhy8phXs= +github.com/ichiban/prolog v1.2.0/go.mod h1:RmvNfGaSktvEVZ7nmpn0gkWa5u0Y3zQcK0G+Pl+ul+s= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY= @@ -29,19 +33,10 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+kI0= -github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM= -github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= -github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= @@ -57,9 +52,8 @@ github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0V github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= @@ -80,6 +74,7 @@ github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+ 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/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -89,31 +84,21 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= -github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= +github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/rules/rules.go b/rules/rules.go new file mode 100644 index 0000000000000000000000000000000000000000..e382a60ed454cfeecf5cd00a939fce6be8e64fd1 --- /dev/null +++ b/rules/rules.go @@ -0,0 +1,76 @@ +// Package rules has the unit conversion rules. +package rules + +import ( + "errors" + + "github.com/ichiban/prolog" +) + +// Engine is the rules engine. +type Engine struct { + p *prolog.Interpreter +} + +var ( + prologKinds = ` + unit_kind(m2, area). + unit_kind(cm2, area). + unit_kind(cm, distance). + unit_kind(m, distance). + unit_kind(km, distance). + unit_kind(feet, distance). + unit_kind(g, mass). + unit_kind(kg, mass). + unit_kind(lb, mass). + unit_kind(cup, volume). + unit_kind(litre, volume). + unit_kind(butter, density). + unit_kind(water, density). +` + prologKindsConvert = ` + convert_kind(mass, volume, density). + convert_kind(volume, area, distance). +` +) + +// New creates a new rules engine. +func New() (*Engine, error) { + ngn := &Engine{ + p: prolog.New(nil, nil), + } + // Treat a string argument as an atom. + if err := ngn.p.Exec(`:- set_prolog_flag(double_quotes, atom).`); err != nil { + return nil, err + } + + if err := ngn.p.Exec(prologKinds); err != nil { + return nil, err + } + + return ngn, nil +} + +// Kind returns the kind of unit. +func (ngn *Engine) Kind(unit string) (string, error) { + sols, err := ngn.p.Query("unit_kind(?, Kind).", unit) + if err != nil { + return "", err + } + defer sols.Close() + + var result string + for sols.Next() { + var kind struct { + Kind string + } + if err := sols.Scan(&kind); err != nil { + return "", err + } + if result != "" { + return "", errors.New("Unit has multiple kinds") + } + result = kind.Kind + } + return result, nil +} diff --git a/rules/rules_test.go b/rules/rules_test.go new file mode 100644 index 0000000000000000000000000000000000000000..f9d244ea9161708ea28e2aa7f96dbdd865c2babf --- /dev/null +++ b/rules/rules_test.go @@ -0,0 +1,32 @@ +package rules + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestKinds(t *testing.T) { + cases := []struct { + name string + query string + result string + }{ + { + "cm kind", + "cm", + "distance", + }, + } + + ngn, err := New() + assert.NoError(t, err) + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + result, err := ngn.Kind(tc.query) + assert.NoError(t, err) + + assert.Equal(t, tc.result, result) + }) + } +}