1
0
mirror of https://github.com/astaxie/beego.git synced 2024-11-22 17:00:55 +00:00

Support Parse Bool with more diffrent values

ParseBool returns the boolean value represented by the string.
It accepts 1, 1.0, t, T, TRUE, true, True, YES, yes, Yes,Y, y, ON, on,
On,
 0, 0.0, f, F, FALSE, false, False, NO, no, No, N,n, OFF, off, Off.
Any other value returns an error.
This commit is contained in:
ysqi 2016-01-23 11:02:40 +08:00
parent af346e871b
commit be544f963e
8 changed files with 202 additions and 118 deletions

View File

@ -106,3 +106,41 @@ func NewConfigData(adapterName string, data []byte) (Configer, error) {
} }
return adapter.ParseData(data) return adapter.ParseData(data)
} }
// ParseBool returns the boolean value represented by the string.
//
// It accepts 1, 1.0, t, T, TRUE, true, True, YES, yes, Yes,Y, y, ON, on, On,
// 0, 0.0, f, F, FALSE, false, False, NO, no, No, N,n, OFF, off, Off.
// Any other value returns an error.
func ParseBool(val interface{}) (value bool, err error) {
if val != nil {
switch v := val.(type) {
case bool:
return v, nil
case string:
switch v {
case "1", "t", "T", "true", "TRUE", "True", "YES", "yes", "Yes", "Y", "y", "ON", "on", "On":
return true, nil
case "0", "f", "F", "false", "FALSE", "False", "NO", "no", "No", "N", "n", "OFF", "off", "Off":
return false, nil
}
case int8, int32, int64:
strV := fmt.Sprintf("%s", v)
if strV == "1" {
return true, nil
} else if strV == "0" {
return false, nil
}
case float64:
if v == 1 {
return true, nil
} else if v == 0 {
return false, nil
}
}
return false, fmt.Errorf("parsing %q: invalid syntax", val)
} else {
return false, fmt.Errorf("parsing <nil>: invalid syntax")
}
}

View File

@ -82,7 +82,7 @@ func (c *fakeConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
} }
func (c *fakeConfigContainer) Bool(key string) (bool, error) { func (c *fakeConfigContainer) Bool(key string) (bool, error) {
return strconv.ParseBool(c.getData(key)) return ParseBool(c.getData(key))
} }
func (c *fakeConfigContainer) DefaultBool(key string, defaultval bool) bool { func (c *fakeConfigContainer) DefaultBool(key string, defaultval bool) bool {

View File

@ -194,7 +194,7 @@ type IniConfigContainer struct {
// Bool returns the boolean value for a given key. // Bool returns the boolean value for a given key.
func (c *IniConfigContainer) Bool(key string) (bool, error) { func (c *IniConfigContainer) Bool(key string) (bool, error) {
return strconv.ParseBool(c.getdata(key)) return ParseBool(c.getdata(key))
} }
// DefaultBool returns the boolean value for a given key. // DefaultBool returns the boolean value for a given key.

View File

@ -15,11 +15,15 @@
package config package config
import ( import (
"fmt"
"os" "os"
"testing" "testing"
) )
var inicontext = ` func TestIni(t *testing.T) {
var (
inicontext = `
;comment one ;comment one
#comment two #comment two
appname = beeapi appname = beeapi
@ -29,6 +33,13 @@ PI = 3.1415976
runmode = "dev" runmode = "dev"
autorender = false autorender = false
copyrequestbody = true copyrequestbody = true
session= on
cookieon= off
newreg = OFF
needlogin = ON
enableSession = Y
enableCookie = N
flag = 1
[demo] [demo]
key1="asta" key1="asta"
key2 = "xie" key2 = "xie"
@ -36,7 +47,31 @@ CaseInsensitive = true
peers = one;two;three peers = one;two;three
` `
func TestIni(t *testing.T) { keyValue = map[string]interface{}{
"appname": "beeapi",
"httpport": 8080,
"mysqlport": int64(3600),
"pi": 3.1415976,
"runmode": "dev",
"autorender": false,
"copyrequestbody": true,
"session": true,
"cookieon": false,
"newreg": false,
"needlogin": true,
"enableSession": true,
"enableCookie": false,
"flag": true,
"demo::key1": "asta",
"demo::key2": "xie",
"demo::CaseInsensitive": true,
"demo::peers": []string{"one", "two", "three"},
"null": "",
"demo2::key1": "",
"error": "",
}
)
f, err := os.Create("testini.conf") f, err := os.Create("testini.conf")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -52,31 +87,31 @@ func TestIni(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if iniconf.String("appname") != "beeapi" { for k, v := range keyValue {
t.Fatal("appname not equal to beeapi") var err error
var value interface{}
switch v.(type) {
case int:
value, err = iniconf.Int(k)
case int64:
value, err = iniconf.Int64(k)
case float64:
value, err = iniconf.Float(k)
case bool:
value, err = iniconf.Bool(k)
case []string:
value = iniconf.Strings(k)
case string:
value = iniconf.String(k)
default:
value, err = iniconf.DIY(k)
} }
if port, err := iniconf.Int("httpport"); err != nil || port != 8080 { if err != nil {
t.Error(port) t.Fatalf("get key %q value fail,err %s", k, err)
t.Fatal(err) } else if fmt.Sprintf("%v", v) != fmt.Sprintf("%v", value) {
t.Fatalf("get key %q value, want %v got %v .", k, v, value)
} }
if port, err := iniconf.Int64("mysqlport"); err != nil || port != 3600 {
t.Error(port)
t.Fatal(err)
}
if pi, err := iniconf.Float("PI"); err != nil || pi != 3.1415976 {
t.Error(pi)
t.Fatal(err)
}
if iniconf.String("runmode") != "dev" {
t.Fatal("runmode not equal to dev")
}
if v, err := iniconf.Bool("autorender"); err != nil || v != false {
t.Error(v)
t.Fatal(err)
}
if v, err := iniconf.Bool("copyrequestbody"); err != nil || v != true {
t.Error(v)
t.Fatal(err)
} }
if err = iniconf.Set("name", "astaxie"); err != nil { if err = iniconf.Set("name", "astaxie"); err != nil {
t.Fatal(err) t.Fatal(err)
@ -84,20 +119,5 @@ func TestIni(t *testing.T) {
if iniconf.String("name") != "astaxie" { if iniconf.String("name") != "astaxie" {
t.Fatal("get name error") t.Fatal("get name error")
} }
if iniconf.String("demo::key1") != "asta" {
t.Fatal("get demo.key1 error")
}
if iniconf.String("demo::key2") != "xie" {
t.Fatal("get demo.key2 error")
}
if v, err := iniconf.Bool("demo::caseinsensitive"); err != nil || v != true {
t.Fatal("get demo.caseinsensitive error")
}
if data := iniconf.Strings("demo::peers"); len(data) != 3 {
t.Fatal("get strings error", data)
} else if data[0] != "one" {
t.Fatal("get first params error not equat to one")
}
} }

View File

@ -17,6 +17,7 @@ package config
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"io/ioutil" "io/ioutil"
"os" "os"
"strings" "strings"
@ -70,12 +71,9 @@ type JSONConfigContainer struct {
func (c *JSONConfigContainer) Bool(key string) (bool, error) { func (c *JSONConfigContainer) Bool(key string) (bool, error) {
val := c.getData(key) val := c.getData(key)
if val != nil { if val != nil {
if v, ok := val.(bool); ok { return ParseBool(val)
return v, nil
} }
return false, errors.New("not bool value") return false, fmt.Errorf("not exist key: %q", key)
}
return false, errors.New("not exist key:" + key)
} }
// DefaultBool return the bool value if has no error // DefaultBool return the bool value if has no error

View File

@ -15,34 +15,14 @@
package config package config
import ( import (
"fmt"
"os" "os"
"testing" "testing"
) )
var jsoncontext = `{ func TestJsonStartsWithArray(t *testing.T) {
"appname": "beeapi",
"testnames": "foo;bar",
"httpport": 8080,
"mysqlport": 3600,
"PI": 3.1415976,
"runmode": "dev",
"autorender": false,
"copyrequestbody": true,
"database": {
"host": "host",
"port": "port",
"database": "database",
"username": "username",
"password": "password",
"conns":{
"maxconnection":12,
"autoconnect":true,
"connectioninfo":"info"
}
}
}`
var jsoncontextwitharray = `[ const jsoncontextwitharray = `[
{ {
"url": "user", "url": "user",
"serviceAPI": "http://www.test.com/user" "serviceAPI": "http://www.test.com/user"
@ -52,8 +32,6 @@ var jsoncontextwitharray = `[
"serviceAPI": "http://www.test.com/employee" "serviceAPI": "http://www.test.com/employee"
} }
]` ]`
func TestJsonStartsWithArray(t *testing.T) {
f, err := os.Create("testjsonWithArray.conf") f, err := os.Create("testjsonWithArray.conf")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -90,6 +68,64 @@ func TestJsonStartsWithArray(t *testing.T) {
} }
func TestJson(t *testing.T) { func TestJson(t *testing.T) {
var (
jsoncontext = `{
"appname": "beeapi",
"testnames": "foo;bar",
"httpport": 8080,
"mysqlport": 3600,
"PI": 3.1415976,
"runmode": "dev",
"autorender": false,
"copyrequestbody": true,
"session": "on",
"cookieon": "off",
"newreg": "OFF",
"needlogin": "ON",
"enableSession": "Y",
"enableCookie": "N",
"flag": 1,
"database": {
"host": "host",
"port": "port",
"database": "database",
"username": "username",
"password": "password",
"conns":{
"maxconnection":12,
"autoconnect":true,
"connectioninfo":"info"
}
}
}`
keyValue = map[string]interface{}{
"appname": "beeapi",
"testnames": []string{"foo", "bar"},
"httpport": 8080,
"mysqlport": int64(3600),
"PI": 3.1415976,
"runmode": "dev",
"autorender": false,
"copyrequestbody": true,
"session": true,
"cookieon": false,
"newreg": false,
"needlogin": true,
"enableSession": true,
"enableCookie": false,
"flag": true,
"database::host": "host",
"database::port": "port",
"database::database": "database",
"database::password": "password",
"database::conns::maxconnection": 12,
"database::conns::autoconnect": true,
"database::conns::connectioninfo": "info",
"unknown": "",
}
)
f, err := os.Create("testjson.conf") f, err := os.Create("testjson.conf")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -105,37 +141,32 @@ func TestJson(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if jsonconf.String("appname") != "beeapi" {
t.Fatal("appname not equal to beeapi") for k, v := range keyValue {
var err error
var value interface{}
switch v.(type) {
case int:
value, err = jsonconf.Int(k)
case int64:
value, err = jsonconf.Int64(k)
case float64:
value, err = jsonconf.Float(k)
case bool:
value, err = jsonconf.Bool(k)
case []string:
value = jsonconf.Strings(k)
case string:
value = jsonconf.String(k)
default:
value, err = jsonconf.DIY(k)
} }
if port, err := jsonconf.Int("httpport"); err != nil || port != 8080 { if err != nil {
t.Error(port) t.Fatalf("get key %q value fatal,%V err %s", k, v, err)
t.Fatal(err) } else if fmt.Sprintf("%v", v) != fmt.Sprintf("%v", value) {
t.Fatalf("get key %q value, want %v got %v .", k, v, value)
} }
if port, err := jsonconf.Int64("mysqlport"); err != nil || port != 3600 {
t.Error(port)
t.Fatal(err)
}
if pi, err := jsonconf.Float("PI"); err != nil || pi != 3.1415976 {
t.Error(pi)
t.Fatal(err)
}
if jsonconf.String("runmode") != "dev" {
t.Fatal("runmode not equal to dev")
}
if v := jsonconf.Strings("unknown"); len(v) > 0 {
t.Fatal("unknown strings, the length should be 0")
}
if v := jsonconf.Strings("testnames"); len(v) != 2 {
t.Fatal("testnames length should be 2")
}
if v, err := jsonconf.Bool("autorender"); err != nil || v != false {
t.Error(v)
t.Fatal(err)
}
if v, err := jsonconf.Bool("copyrequestbody"); err != nil || v != true {
t.Error(v)
t.Fatal(err)
} }
if err = jsonconf.Set("name", "astaxie"); err != nil { if err = jsonconf.Set("name", "astaxie"); err != nil {
t.Fatal(err) t.Fatal(err)
@ -143,15 +174,7 @@ func TestJson(t *testing.T) {
if jsonconf.String("name") != "astaxie" { if jsonconf.String("name") != "astaxie" {
t.Fatal("get name error") t.Fatal("get name error")
} }
if jsonconf.String("database::host") != "host" {
t.Fatal("get database::host error")
}
if jsonconf.String("database::conns::connectioninfo") != "info" {
t.Fatal("get database::conns::connectioninfo error")
}
if maxconnection, err := jsonconf.Int("database::conns::maxconnection"); err != nil || maxconnection != 12 {
t.Fatal("get database::conns::maxconnection error")
}
if db, err := jsonconf.DIY("database"); err != nil { if db, err := jsonconf.DIY("database"); err != nil {
t.Fatal(err) t.Fatal(err)
} else if m, ok := db.(map[string]interface{}); !ok { } else if m, ok := db.(map[string]interface{}); !ok {

View File

@ -92,7 +92,11 @@ type ConfigContainer struct {
// Bool returns the boolean value for a given key. // Bool returns the boolean value for a given key.
func (c *ConfigContainer) Bool(key string) (bool, error) { func (c *ConfigContainer) Bool(key string) (bool, error) {
return strconv.ParseBool(c.data[key].(string)) if v, ok := c.data[key]; ok {
return config.ParseBool(v)
} else {
return false, fmt.Errorf("not exist key: %q", key)
}
} }
// DefaultBool return the bool value if has no error // DefaultBool return the bool value if has no error

View File

@ -121,10 +121,11 @@ type ConfigContainer struct {
// Bool returns the boolean value for a given key. // Bool returns the boolean value for a given key.
func (c *ConfigContainer) Bool(key string) (bool, error) { func (c *ConfigContainer) Bool(key string) (bool, error) {
if v, ok := c.data[key].(bool); ok { if v, ok := c.data[key]; ok {
return v, nil return config.ParseBool(v)
} else {
return false, fmt.Errorf("not exist key: %q", key)
} }
return false, errors.New("not bool value")
} }
// DefaultBool return the bool value if has no error // DefaultBool return the bool value if has no error