func TestDecode_NilInterfaceHook(t *testing.T) { t.Parallel() input := map[string]interface{}{ "w": "", } decodeHook := func(f, t reflect.Type, v interface{}) (interface{}, error) { if t.String() == "io.Writer" { return nil, nil } return v, nil } var result NilInterface config := &DecoderConfig{ DecodeHook: decodeHook, Result: &result, } decoder, err := NewDecoder(config) if err != nil { t.Fatalf("err: %s", err) } err = decoder.Decode(input) if err != nil { t.Fatalf("got an err: %s", err) } if result.W != nil { t.Errorf("W should be nil: %#v", result.W) } }
func TestSerialDeserialization(t *testing.T) { f1 := &FileId{VolumeId: 345, Key: 8698, Hashcode: 23849095} log.Println("vid", f1.VolumeId, "key", f1.Key, "hash", f1.Hashcode) f2 := ParseFileId(t.String()) log.Println("vvid", f2.VolumeId, "vkey", f2.Key, "vhash", f2.Hashcode) }
func TestNNF(t *testing.T) { // Build a simple BNF aGrammar description aGrammar. gb := parser.OpenGrammarBuilder() gb.Name("a4"). Terminals("a"). Nonterminals("S", "A", "E"). Rule().Lhs("`*").Rhs("S", "`."). Rule().Lhs("S").Rhs("A", "A", "A", "A"). Rule().Lhs("A").Rhs("a"). Rule().Lhs("A").Rhs("E"). Rule().Lhs("E").Rhs("`e") g, err := gb.Build() if err != nil { t.Error(err) return } var aGrammar parser.Grammar var rTransform parser.SyntaxTreeTransform nnf, err := IsNihilisticNormalForm(g) if err != nil { t.Error() return } if !nnf { fmt.Println("Grammar is not NNF, transforming.") aGrammar, rTransform, err = GetNihilisticAugmentGrammar(g) if err != nil { t.Error(err) return } } else { t.Error("Grammar returned NNF.") return } fmt.Println("Name: " + aGrammar.Name()) terms := make([]string, aGrammar.NumTerminals()) for i, t := range aGrammar.Terminals() { terms[i] = t.String() } nterms := make([]string, aGrammar.NumNonterminals()) for i, t := range aGrammar.Nonterminals() { nterms[i] = t.String() } fmt.Println("Terminals: " + strings.Join(terms, ", ")) fmt.Println("Nonterminals: " + strings.Join(nterms, ", ")) fmt.Println("Productions:") for _, p := range aGrammar.Productions() { fmt.Println(" " + p.String()) } rTransform = rTransform }
func TestGraphGenerator(t *testing.T) { testData := []struct { size int n int want []string }{ { size: 1, n: 0, want: nil, }, { size: 1, n: 1, want: []string{ "/gn<0>\t\"follow\"@[]\t/gn<0>", }, }, { size: 2, n: 4, want: []string{ "/gn<0>\t\"follow\"@[]\t/gn<0>", "/gn<0>\t\"follow\"@[]\t/gn<1>", "/gn<1>\t\"follow\"@[]\t/gn<0>", "/gn<1>\t\"follow\"@[]\t/gn<1>", }, }, } for _, entry := range testData { g, err := NewRandomGraph(entry.size) if err != nil { t.Fatalf("graph.NewRandomGraph(%d) should have never failed, %v.", entry.size, err) } trpls, err := g.Generate(entry.n) if err != nil { t.Fatalf("graph.NewRandomGraph(%d) should have never failed, %v.", entry.size, err) } if got, want := len(trpls), len(entry.want); got != want { t.Fatalf("g.Generate(%d) returned the wrong number of triples; got %d, want %d.", entry.n, got, want) } var tts []string for _, t := range trpls { tts = append(tts, t.String()) } sort.Strings(tts) if got, want := tts, entry.want; !reflect.DeepEqual(got, want) { t.Fatalf("g.Generate(%d) returned the wrong number of triples; got %v, want %v.", entry.n, got, want) } } }
func TestDo(t *testing.T) { // For now, we just pile stuff into this one function. // ToDo: Don't do that. g, _ := GetGraph("config.test") g.WriteIndexedTriple(TripleFromStrings("aaa", "p1", "bbb", "today"), nil) g.WriteIndexedTriple(TripleFromStrings("aaa", "p1", "fff", "today"), nil) g.WriteIndexedTriple(TripleFromStrings("aaa", "p5", "jjj", "today"), nil) g.WriteIndexedTriple(TripleFromStrings("bbb", "p2", "ccc", "today"), nil) g.WriteIndexedTriple(TripleFromStrings("ccc", "p3", "ddd", "today"), nil) g.WriteIndexedTriple(TripleFromStrings("ccc", "p3", "eee", "today"), nil) g.WriteIndexedTriple(TripleFromStrings("ggg", "p4", "ccc", "today"), nil) g.WriteIndexedTriple(TripleFromStrings("ggg", "p1", "hhh", "today"), nil) g.WriteIndexedTriple(TripleFromStrings("ggg", "p1", "iii", "today"), nil) g.DoAll(nil, 100, func(t *Triple) bool { fmt.Printf("triple %v\n", t.String()) return true }) fmt.Println("DoS") g.DoVertexes(nil, 30, func(s []byte) bool { Out([]byte("p1")).Walk(g, s).Print() return true }) i := g.NewVertexIterator() for { v, ok := i.Next() if !ok { break } fmt.Printf("v %s\n", v) } i = g.NewVertexIterator() for { v := i.NextVertex() if v == "" { break } fmt.Printf("nv %s\n", v) } g.Close() }
func TestID(t *testing.T) { ts := []T{ Make("test").T(), Int(7), Str("hello"), } for _, t := range ts { it := IDT(t).T() if it.String() != t.String() { fmt.Println("%v != %v", t, it) } s := ConstC{t} is := IDC(s).C() if s.String() != is.String() { fmt.Println("%v != %v", s, is) } } }
func TestTokenized(t *testing.T) { Convey("Tokenizing data from a request works as expected", t, func() { // Let's setup a test server. var ts *httptest.Server ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" && r.URL.Path == "/test" { defer r.Body.Close() w.Header().Add("X-Custom-Hdr", "Custom Header") w.Header().Add("Set-Cookie", "session_id=42 ; Path=/") w.WriteHeader(200) fmt.Fprint(w, fmt.Sprintf(`{"URL": "%s", "json": true, "foolMeOnce": "shame on you"}`, r.URL)) } })) Convey("Given a Tokenized objects, confirm that it formats the right information if does not format anything.", func() { t := Tokenized{Data: "test"} So(t.Format(nil), ShouldEqual, "test") So(t.String(), ShouldEqual, "{Tokenized with data}") }) Convey("Given a Tokenized objects, confirm that it formats the right information if response is nil.", func() { t := Tokenized{Data: "test", Cookie: "ChocChip"} So(t.Format(nil), ShouldEqual, "test") So(t.String(), ShouldEqual, "{Tokenized with cookie with data}") }) Convey("Given a Tokenized objects, confirm that it formats the right information.", func() { example := `<headers responseToken="resp" headerToken="hdr" cookieToken="cke"> X-Fool:NotAMonkey resp/foolMeOnce Cookie:test=true;session_id=cke/session_id Some-Header:hdr/X-Custom-Hdr X-Cannot-Decode: resp/json </headers>` out := Tokenized{} xml.Unmarshal([]byte(example), &out) gresp, _ := goreq.Request{Uri: ts.URL + "/test"}.Do() resp := Response{} resp.FromGoResp(gresp, nil, time.Now()) expectations := []string{"", "X-Fool:NotAMonkey shame on you", "Cookie:test=true;session_id=42", "Some-Header:Custom Header", "X-Cannot-Decode:", ""} for pos, line := range strings.Split(out.Format(&resp), "\n") { So(strings.TrimSpace(line), ShouldEqual, expectations[pos]) } So(out.String(), ShouldEqual, "{Tokenized with cookie with header with data}") }) }) }
/* First: bnf: ntdecl, NONTERM ntdecl: ntdecl, NONTERM def: ntort, IDENTIFIER, NONTERM ntort: IDENTIFIER, NONTERM <bnf> `. <ntdecl> <bnf>. <bnf> PIPE NONTERM COLEQ <ntort>. COLEQ <def> <def> <ntdecl>. PIPE <def> <ntort> <def>. <def> IDENTIFIER <ntort>. <bnf> `. <ntdecl> <bnf>. <bnf> PIPE `. NONTERM COLEQ <ntort>. <def>. <def> <ntdecl>. <bnf>. <bnf> PIPE `. COLEQ <def> <def> <ntdecl>. <bnf>. <bnf> PIPE `. PIPE <def> <ntort> <def>. <def> <ntdecl>. <bnf>. <bnf> PIPE `. IDENTIFIER <ntort>. <def>. <def> <ntdecl>. <bnf>. <bnf> PIPE `. <bnf> `. <ntdecl> <bnf> PIPE `. <def> <bnf> PIPE `. <ntort> <def> <bnf> PIPE `. NONTERM <def> <bnf> COLEQ PIPE `. COLEQ <def> PIPE <def> IDENTIFIER <def> <bnf> PIPE `. 0 `* := <bnf> `. 1 <bnf> := <ntdecl> 2 | <ntdecl> <bnf> 3 <ntdecl> := NONTERM COLEQ <def> 4 | <ntdecl> PIPE <def> 5 <def> := <ntort> 6 | <ntort> <def> 7 <ntort> := IDENTIFIER | NONTERM Reading <ntdecl> ... .NT 3,ntdecl: . NT C <def> 4,ntdecl: . <ntdecl> P <def> 3,ntdecl: NT C . <def> 4,ntdecl: <ntdecl> P . <def> .ID 3,ntdecl: NT C . <def> 4,ntdecl: <ntdecl> P . <def> .C 3,ntdecl: NT . C <def> .P 4,ntdecl: <ntdecl> . P <def> */ func TestGrammarBuilder(t *testing.T) { // Build a simple BNF grammar description grammar. gb := OpenGrammarBuilder() gb.Terminals("NONTERM", "COLEQ", "PIPE", "IDENTIFIER"). Nonterminals("bnf", "ntdecl", "def", "ntort"). Rule().Lhs("bnf").Rhs("ntdecl"). Rule().Lhs("bnf").Rhs("ntdecl", "bnf"). Rule().Lhs("ntdecl").Rhs("NONTERM", "COLEQ", "def"). Rule().Lhs("ntdecl").Rhs("ntdecl", "PIPE", "def"). Rule().Lhs("def").Rhs("ntort"). Rule().Lhs("def").Rhs("ntort", "def"). Rule().Lhs("ntort").Rhs("IDENTIFIER"). Rule().Lhs("ntort").Rhs("NONTERM"). Rule().Lhs("`*").Rhs("bnf", "`."). Name("simple-bnf") grammar, err := gb.Build() if err != nil { t.Error(err) } fmt.Println("Name: " + grammar.Name()) terms := make([]string, grammar.NumTerminals()) for i, t := range grammar.Terminals() { terms[i] = t.String() } nterms := make([]string, grammar.NumNonterminals()) for i, t := range grammar.Nonterminals() { nterms[i] = t.String() } fmt.Println("Terminals: " + strings.Join(terms, ", ")) fmt.Println("Nonterminals: " + strings.Join(nterms, ", ")) fmt.Println("Productions:") for _, p := range grammar.Productions() { fmt.Println(" " + p.String()) } }
func TestLexer(t *testing.T) { Convey("basic lexer testing", t, func() { for _, c := range []Case{ {`"`, `ILLEGAL "unterminated string: ''"`, ""}, {"", `EOF ""`, ""}, {"\n ", `EOF ""`, ""}, {"; asdf", `COMMENT "; asdf"`, ""}, {"; asdf\n", `COMMENT "; asdf\n"`, ""}, {"(", `LEFT_PAREN "("`, ""}, {")", `RIGHT_PAREN ")"`, ""}, {" . ", `DOT "."`, ""}, {"'", `QUOTE "'"`, ""}, {"-", `SYMBOL "-"`, ""}, {"-1", `NUMBER "-1"`, ""}, {".", `NUMBER "."`, ""}, {"123", `NUMBER "123"`, ""}, {"-abc", `SYMBOL "-abc"`, ""}, {"abc", `SYMBOL "abc"`, ""}, {`"abc"`, `STRING "abc"`, ""}, {`"abc\`, `ILLEGAL "unterminated string: \"abc\""`, ""}, {"#t", `TRUE "t"`, ""}, {"#f", `FALSE "f"`, ""}, {"#n", `ILLEGAL "unsupported hash code #n"`, ""}, {"a(", `SYMBOL "a"`, ""}, {"12(", `NUMBER "12"`, ""}, } { doLex(c.value, c.expected, c.err) } Convey("Unknown tokeen", func() { t := Token(500) So(t.String(), ShouldEqual, "Unknown token: 500") }) }) }
func TestIterator(t *testing.T) { tmpDir, err := ioutil.TempDir(os.TempDir(), "cayley_test") if err != nil { t.Fatalf("Could not create working directory: %v", err) } defer os.RemoveAll(tmpDir) t.Log(tmpDir) err = createNewLevelDB(tmpDir, nil) if err != nil { t.Fatal("Failed to create LevelDB database.") } qs, err := newQuadStore(tmpDir, nil) if qs == nil || err != nil { t.Error("Failed to create leveldb QuadStore.") } w, _ := writer.NewSingleReplication(qs, nil) w.AddQuadSet(makeQuadSet()) var it graph.Iterator it = qs.NodesAllIterator() if it == nil { t.Fatal("Got nil iterator.") } size, exact := it.Size() if size <= 0 || size >= 20 { t.Errorf("Unexpected size, got:%d expect:(0, 20)", size) } if exact { t.Errorf("Got unexpected exact result.") } if typ := it.Type(); typ != graph.All { t.Errorf("Unexpected iterator type, got:%v expect:%v", typ, graph.All) } optIt, changed := it.Optimize() if changed || optIt != it { t.Errorf("Optimize unexpectedly changed iterator.") } expect := []string{ "A", "B", "C", "D", "E", "F", "G", "follows", "status", "cool", "status_graph", } sort.Strings(expect) for i := 0; i < 2; i++ { got := iteratedNames(qs, it) sort.Strings(got) if !reflect.DeepEqual(got, expect) { t.Errorf("Unexpected iterated result on repeat %d, got:%v expect:%v", i, got, expect) } it.Reset() } for _, pq := range expect { if !it.Contains(qs.ValueOf(pq)) { t.Errorf("Failed to find and check %q correctly", pq) } } // FIXME(kortschak) Why does this fail? /* for _, pq := range []string{"baller"} { if it.Contains(qs.ValueOf(pq)) { t.Errorf("Failed to check %q correctly", pq) } } */ it.Reset() it = qs.QuadsAllIterator() graph.Next(it) q := qs.Quad(it.Result()) set := makeQuadSet() var ok bool for _, t := range set { if t.String() == q.String() { ok = true break } } if !ok { t.Errorf("Failed to find %q during iteration, got:%q", q, set) } qs.Close() }
func Test_Values(t *testing.T) { Convey("Test getting and setting values", t, func() { cfg, err := Load([]byte(_CONF_DATA), "testdata/conf.ini") So(err, ShouldBeNil) So(cfg, ShouldNotBeNil) Convey("Get values in default section", func() { sec := cfg.Section("") So(sec, ShouldNotBeNil) So(sec.Key("NAME").Value(), ShouldEqual, "ini") So(sec.Key("NAME").String(), ShouldEqual, "ini") So(sec.Key("NAME").Comment, ShouldEqual, "; Package name") So(sec.Key("IMPORT_PATH").String(), ShouldEqual, "gopkg.in/ini.v1") }) Convey("Get values in non-default section", func() { sec := cfg.Section("author") So(sec, ShouldNotBeNil) So(sec.Key("NAME").String(), ShouldEqual, "Unknwon") So(sec.Key("GITHUB").String(), ShouldEqual, "https://github.com/Unknwon") sec = cfg.Section("package") So(sec, ShouldNotBeNil) So(sec.Key("CLONE_URL").String(), ShouldEqual, "https://gopkg.in/ini.v1") }) Convey("Get auto-increment key names", func() { keys := cfg.Section("features").Keys() for i, k := range keys { So(k.Name(), ShouldEqual, fmt.Sprintf("#%d", i+1)) } }) Convey("Get overwrite value", func() { So(cfg.Section("author").Key("E-MAIL").String(), ShouldEqual, "*****@*****.**") }) Convey("Get sections", func() { sections := cfg.Sections() for i, name := range []string{DEFAULT_SECTION, "author", "package", "package.sub", "features", "types", "array", "note", "advance"} { So(sections[i].Name(), ShouldEqual, name) } }) Convey("Get parent section value", func() { So(cfg.Section("package.sub").Key("CLONE_URL").String(), ShouldEqual, "https://gopkg.in/ini.v1") }) Convey("Get multiple line value", func() { So(cfg.Section("author").Key("BIO").String(), ShouldEqual, "Gopher.\nCoding addict.\nGood man.\n") }) Convey("Get values with type", func() { sec := cfg.Section("types") v1, err := sec.Key("BOOL").Bool() So(err, ShouldBeNil) So(v1, ShouldBeTrue) v1, err = sec.Key("BOOL_FALSE").Bool() So(err, ShouldBeNil) So(v1, ShouldBeFalse) v2, err := sec.Key("FLOAT64").Float64() So(err, ShouldBeNil) So(v2, ShouldEqual, 1.25) v3, err := sec.Key("INT").Int() So(err, ShouldBeNil) So(v3, ShouldEqual, 10) v4, err := sec.Key("INT").Int64() So(err, ShouldBeNil) So(v4, ShouldEqual, 10) t, err := time.Parse(time.RFC3339, "2015-01-01T20:17:05Z") So(err, ShouldBeNil) v5, err := sec.Key("TIME").Time() So(err, ShouldBeNil) So(v5.String(), ShouldEqual, t.String()) Convey("Must get values with type", func() { So(sec.Key("STRING").MustString("404"), ShouldEqual, "str") So(sec.Key("BOOL").MustBool(), ShouldBeTrue) So(sec.Key("FLOAT64").MustFloat64(), ShouldEqual, 1.25) So(sec.Key("INT").MustInt(), ShouldEqual, 10) So(sec.Key("INT").MustInt64(), ShouldEqual, 10) So(sec.Key("TIME").MustTime().String(), ShouldEqual, t.String()) Convey("Must get values with default value", func() { So(sec.Key("STRING_404").MustString("404"), ShouldEqual, "404") So(sec.Key("BOOL_404").MustBool(true), ShouldBeTrue) So(sec.Key("FLOAT64_404").MustFloat64(2.5), ShouldEqual, 2.5) So(sec.Key("INT_404").MustInt(15), ShouldEqual, 15) So(sec.Key("INT_404").MustInt64(15), ShouldEqual, 15) t, err := time.Parse(time.RFC3339, "2014-01-01T20:17:05Z") So(err, ShouldBeNil) So(sec.Key("TIME_404").MustTime(t).String(), ShouldEqual, t.String()) }) }) }) Convey("Get value with candidates", func() { sec := cfg.Section("types") So(sec.Key("STRING").In("", []string{"str", "arr", "types"}), ShouldEqual, "str") So(sec.Key("FLOAT64").InFloat64(0, []float64{1.25, 2.5, 3.75}), ShouldEqual, 1.25) So(sec.Key("INT").InInt(0, []int{10, 20, 30}), ShouldEqual, 10) So(sec.Key("INT").InInt64(0, []int64{10, 20, 30}), ShouldEqual, 10) zt, err := time.Parse(time.RFC3339, "0001-01-01T01:00:00Z") So(err, ShouldBeNil) t, err := time.Parse(time.RFC3339, "2015-01-01T20:17:05Z") So(err, ShouldBeNil) So(sec.Key("TIME").InTime(zt, []time.Time{t, time.Now(), time.Now().Add(1 * time.Second)}).String(), ShouldEqual, t.String()) Convey("Get value with candidates and default value", func() { So(sec.Key("STRING_404").In("str", []string{"str", "arr", "types"}), ShouldEqual, "str") So(sec.Key("FLOAT64_404").InFloat64(1.25, []float64{1.25, 2.5, 3.75}), ShouldEqual, 1.25) So(sec.Key("INT_404").InInt(10, []int{10, 20, 30}), ShouldEqual, 10) So(sec.Key("INT64_404").InInt64(10, []int64{10, 20, 30}), ShouldEqual, 10) So(sec.Key("TIME_404").InTime(t, []time.Time{time.Now(), time.Now(), time.Now().Add(1 * time.Second)}).String(), ShouldEqual, t.String()) }) }) Convey("Get values in range", func() { sec := cfg.Section("types") So(sec.Key("FLOAT64").RangeFloat64(0, 1, 2), ShouldEqual, 1.25) So(sec.Key("INT").RangeInt(0, 10, 20), ShouldEqual, 10) So(sec.Key("INT").RangeInt64(0, 10, 20), ShouldEqual, 10) minT, err := time.Parse(time.RFC3339, "0001-01-01T01:00:00Z") So(err, ShouldBeNil) midT, err := time.Parse(time.RFC3339, "2013-01-01T01:00:00Z") So(err, ShouldBeNil) maxT, err := time.Parse(time.RFC3339, "9999-01-01T01:00:00Z") So(err, ShouldBeNil) t, err := time.Parse(time.RFC3339, "2015-01-01T20:17:05Z") So(err, ShouldBeNil) So(sec.Key("TIME").RangeTime(t, minT, maxT).String(), ShouldEqual, t.String()) Convey("Get value in range with default value", func() { So(sec.Key("FLOAT64").RangeFloat64(5, 0, 1), ShouldEqual, 5) So(sec.Key("INT").RangeInt(7, 0, 5), ShouldEqual, 7) So(sec.Key("INT").RangeInt64(7, 0, 5), ShouldEqual, 7) So(sec.Key("TIME").RangeTime(t, minT, midT).String(), ShouldEqual, t.String()) }) }) Convey("Get values into slice", func() { sec := cfg.Section("array") So(strings.Join(sec.Key("STRINGS").Strings(","), ","), ShouldEqual, "en,zh,de") So(len(sec.Key("STRINGS_404").Strings(",")), ShouldEqual, 0) vals1 := sec.Key("FLOAT64S").Float64s(",") for i, v := range []float64{1.1, 2.2, 3.3} { So(vals1[i], ShouldEqual, v) } vals2 := sec.Key("INTS").Ints(",") for i, v := range []int{1, 2, 3} { So(vals2[i], ShouldEqual, v) } vals3 := sec.Key("INTS").Int64s(",") for i, v := range []int64{1, 2, 3} { So(vals3[i], ShouldEqual, v) } t, err := time.Parse(time.RFC3339, "2015-01-01T20:17:05Z") So(err, ShouldBeNil) vals4 := sec.Key("TIMES").Times(",") for i, v := range []time.Time{t, t, t} { So(vals4[i].String(), ShouldEqual, v.String()) } }) Convey("Get key hash", func() { cfg.Section("").KeysHash() }) Convey("Set key value", func() { k := cfg.Section("author").Key("NAME") k.SetValue("无闻") So(k.String(), ShouldEqual, "无闻") }) Convey("Get key strings", func() { So(strings.Join(cfg.Section("types").KeyStrings(), ","), ShouldEqual, "STRING,BOOL,BOOL_FALSE,FLOAT64,INT,TIME") }) Convey("Delete a key", func() { cfg.Section("package.sub").DeleteKey("UNUSED_KEY") _, err := cfg.Section("package.sub").GetKey("UNUSED_KEY") So(err, ShouldNotBeNil) }) Convey("Get section strings", func() { So(strings.Join(cfg.SectionStrings(), ","), ShouldEqual, "DEFAULT,author,package,package.sub,features,types,array,note,advance") }) Convey("Delete a section", func() { cfg.DeleteSection("") So(cfg.SectionStrings()[0], ShouldNotEqual, DEFAULT_SECTION) }) Convey("Create new sections", func() { cfg.NewSections("test", "test2") _, err := cfg.GetSection("test") So(err, ShouldBeNil) _, err = cfg.GetSection("test2") So(err, ShouldBeNil) }) }) Convey("Test getting and setting bad values", t, func() { cfg, err := Load([]byte(_CONF_DATA), "testdata/conf.ini") So(err, ShouldBeNil) So(cfg, ShouldNotBeNil) Convey("Create new key with empty name", func() { k, err := cfg.Section("").NewKey("", "") So(err, ShouldNotBeNil) So(k, ShouldBeNil) }) Convey("Create new section with empty name", func() { s, err := cfg.NewSection("") So(err, ShouldNotBeNil) So(s, ShouldBeNil) }) Convey("Create new sections with empty name", func() { So(cfg.NewSections(""), ShouldNotBeNil) }) Convey("Get section that not exists", func() { s, err := cfg.GetSection("404") So(err, ShouldNotBeNil) So(s, ShouldBeNil) s = cfg.Section("404") So(s, ShouldNotBeNil) }) }) }
func Test_Struct(t *testing.T) { Convey("Map to struct", t, func() { Convey("Map file to struct", func() { ts := new(testStruct) So(MapTo(ts, []byte(_CONF_DATA_STRUCT)), ShouldBeNil) So(ts.Name, ShouldEqual, "Unknwon") So(ts.Age, ShouldEqual, 21) So(ts.Male, ShouldBeTrue) So(ts.Money, ShouldEqual, 1.25) So(ts.Unsigned, ShouldEqual, 3) t, err := time.Parse(time.RFC3339, "1993-10-07T20:17:05Z") So(err, ShouldBeNil) So(ts.Born.String(), ShouldEqual, t.String()) dur, err := time.ParseDuration("2h45m") So(err, ShouldBeNil) So(ts.Time.Seconds(), ShouldEqual, dur.Seconds()) So(strings.Join(ts.Others.Cities, ","), ShouldEqual, "HangZhou,Boston") So(ts.Others.Visits[0].String(), ShouldEqual, t.String()) So(ts.Others.Note, ShouldEqual, "Hello world!") So(ts.testEmbeded.GPA, ShouldEqual, 2.8) }) Convey("Map section to struct", func() { foobar := new(fooBar) f, err := Load([]byte(_CONF_DATA_STRUCT)) So(err, ShouldBeNil) So(f.Section("foo.bar").MapTo(foobar), ShouldBeNil) So(foobar.Here, ShouldEqual, "there") So(foobar.When, ShouldEqual, "then") }) Convey("Map to non-pointer struct", func() { cfg, err := Load([]byte(_CONF_DATA_STRUCT)) So(err, ShouldBeNil) So(cfg, ShouldNotBeNil) So(cfg.MapTo(testStruct{}), ShouldNotBeNil) }) Convey("Map to unsupported type", func() { cfg, err := Load([]byte(_CONF_DATA_STRUCT)) So(err, ShouldBeNil) So(cfg, ShouldNotBeNil) cfg.NameMapper = func(raw string) string { if raw == "Byte" { return "NAME" } return raw } So(cfg.MapTo(&unsupport{}), ShouldNotBeNil) So(cfg.MapTo(&unsupport2{}), ShouldNotBeNil) So(cfg.MapTo(&unsupport4{}), ShouldNotBeNil) }) Convey("Map from invalid data source", func() { So(MapTo(&testStruct{}, "hi"), ShouldNotBeNil) }) Convey("Map to wrong types and gain default values", func() { cfg, err := Load([]byte(_INVALID_DATA_CONF_STRUCT)) So(err, ShouldBeNil) t, err := time.Parse(time.RFC3339, "1993-10-07T20:17:05Z") So(err, ShouldBeNil) dv := &defaultValue{"Joe", 10, true, 1.25, t, []string{"HangZhou", "Boston"}} So(cfg.MapTo(dv), ShouldBeNil) So(dv.Name, ShouldEqual, "Joe") So(dv.Age, ShouldEqual, 10) So(dv.Male, ShouldBeTrue) So(dv.Money, ShouldEqual, 1.25) So(dv.Born.String(), ShouldEqual, t.String()) So(strings.Join(dv.Cities, ","), ShouldEqual, "HangZhou,Boston") }) }) Convey("Reflect from struct", t, func() { type Embeded struct { Dates []time.Time `delim:"|"` Places []string None []int } type Author struct { Name string `ini:"NAME"` Male bool Age int GPA float64 NeverMind string `ini:"-"` *Embeded `ini:"infos"` } a := &Author{"Unknwon", true, 21, 2.8, "", &Embeded{ []time.Time{time.Now(), time.Now()}, []string{"HangZhou", "Boston"}, []int{}, }} cfg := Empty() So(ReflectFrom(cfg, a), ShouldBeNil) cfg.SaveTo("testdata/conf_reflect.ini") Convey("Reflect from non-point struct", func() { So(ReflectFrom(cfg, Author{}), ShouldNotBeNil) }) }) }
func Test_Values(t *testing.T) { Convey("Test getting and setting values", t, func() { cfg, err := Load([]byte(_CONF_DATA), "testdata/conf.ini") So(err, ShouldBeNil) So(cfg, ShouldNotBeNil) Convey("Get values in default section", func() { sec := cfg.Section("") So(sec, ShouldNotBeNil) So(sec.Key("NAME").Value(), ShouldEqual, "ini") So(sec.Key("NAME").String(), ShouldEqual, "ini") So(sec.Key("NAME").Validate(func(in string) string { return in }), ShouldEqual, "ini") So(sec.Key("NAME").Comment, ShouldEqual, "; Package name") So(sec.Key("IMPORT_PATH").String(), ShouldEqual, "gopkg.in/ini.v1") }) Convey("Get values in non-default section", func() { sec := cfg.Section("author") So(sec, ShouldNotBeNil) So(sec.Key("NAME").String(), ShouldEqual, "Unknwon") So(sec.Key("GITHUB").String(), ShouldEqual, "https://github.com/Unknwon") sec = cfg.Section("package") So(sec, ShouldNotBeNil) So(sec.Key("CLONE_URL").String(), ShouldEqual, "https://gopkg.in/ini.v1") }) Convey("Get auto-increment key names", func() { keys := cfg.Section("features").Keys() for i, k := range keys { So(k.Name(), ShouldEqual, fmt.Sprintf("#%d", i+1)) } }) Convey("Get overwrite value", func() { So(cfg.Section("author").Key("E-MAIL").String(), ShouldEqual, "*****@*****.**") }) Convey("Get sections", func() { sections := cfg.Sections() for i, name := range []string{DEFAULT_SECTION, "author", "package", "package.sub", "features", "types", "array", "note", "comments", "advance"} { So(sections[i].Name(), ShouldEqual, name) } }) Convey("Get parent section value", func() { So(cfg.Section("package.sub").Key("CLONE_URL").String(), ShouldEqual, "https://gopkg.in/ini.v1") So(cfg.Section("package.fake.sub").Key("CLONE_URL").String(), ShouldEqual, "https://gopkg.in/ini.v1") }) Convey("Get multiple line value", func() { So(cfg.Section("author").Key("BIO").String(), ShouldEqual, "Gopher.\nCoding addict.\nGood man.\n") }) Convey("Get values with type", func() { sec := cfg.Section("types") v1, err := sec.Key("BOOL").Bool() So(err, ShouldBeNil) So(v1, ShouldBeTrue) v1, err = sec.Key("BOOL_FALSE").Bool() So(err, ShouldBeNil) So(v1, ShouldBeFalse) v2, err := sec.Key("FLOAT64").Float64() So(err, ShouldBeNil) So(v2, ShouldEqual, 1.25) v3, err := sec.Key("INT").Int() So(err, ShouldBeNil) So(v3, ShouldEqual, 10) v4, err := sec.Key("INT").Int64() So(err, ShouldBeNil) So(v4, ShouldEqual, 10) v5, err := sec.Key("UINT").Uint() So(err, ShouldBeNil) So(v5, ShouldEqual, 3) v6, err := sec.Key("UINT").Uint64() So(err, ShouldBeNil) So(v6, ShouldEqual, 3) t, err := time.Parse(time.RFC3339, "2015-01-01T20:17:05Z") So(err, ShouldBeNil) v7, err := sec.Key("TIME").Time() So(err, ShouldBeNil) So(v7.String(), ShouldEqual, t.String()) Convey("Must get values with type", func() { So(sec.Key("STRING").MustString("404"), ShouldEqual, "str") So(sec.Key("BOOL").MustBool(), ShouldBeTrue) So(sec.Key("FLOAT64").MustFloat64(), ShouldEqual, 1.25) So(sec.Key("INT").MustInt(), ShouldEqual, 10) So(sec.Key("INT").MustInt64(), ShouldEqual, 10) So(sec.Key("UINT").MustUint(), ShouldEqual, 3) So(sec.Key("UINT").MustUint64(), ShouldEqual, 3) So(sec.Key("TIME").MustTime().String(), ShouldEqual, t.String()) dur, err := time.ParseDuration("2h45m") So(err, ShouldBeNil) So(sec.Key("DURATION").MustDuration().Seconds(), ShouldEqual, dur.Seconds()) Convey("Must get values with default value", func() { So(sec.Key("STRING_404").MustString("404"), ShouldEqual, "404") So(sec.Key("BOOL_404").MustBool(true), ShouldBeTrue) So(sec.Key("FLOAT64_404").MustFloat64(2.5), ShouldEqual, 2.5) So(sec.Key("INT_404").MustInt(15), ShouldEqual, 15) So(sec.Key("INT_404").MustInt64(15), ShouldEqual, 15) So(sec.Key("UINT_404").MustUint(6), ShouldEqual, 6) So(sec.Key("UINT_404").MustUint64(6), ShouldEqual, 6) t, err := time.Parse(time.RFC3339, "2014-01-01T20:17:05Z") So(err, ShouldBeNil) So(sec.Key("TIME_404").MustTime(t).String(), ShouldEqual, t.String()) So(sec.Key("DURATION_404").MustDuration(dur).Seconds(), ShouldEqual, dur.Seconds()) }) }) }) Convey("Get value with candidates", func() { sec := cfg.Section("types") So(sec.Key("STRING").In("", []string{"str", "arr", "types"}), ShouldEqual, "str") So(sec.Key("FLOAT64").InFloat64(0, []float64{1.25, 2.5, 3.75}), ShouldEqual, 1.25) So(sec.Key("INT").InInt(0, []int{10, 20, 30}), ShouldEqual, 10) So(sec.Key("INT").InInt64(0, []int64{10, 20, 30}), ShouldEqual, 10) So(sec.Key("UINT").InUint(0, []uint{3, 6, 9}), ShouldEqual, 3) So(sec.Key("UINT").InUint64(0, []uint64{3, 6, 9}), ShouldEqual, 3) zt, err := time.Parse(time.RFC3339, "0001-01-01T01:00:00Z") So(err, ShouldBeNil) t, err := time.Parse(time.RFC3339, "2015-01-01T20:17:05Z") So(err, ShouldBeNil) So(sec.Key("TIME").InTime(zt, []time.Time{t, time.Now(), time.Now().Add(1 * time.Second)}).String(), ShouldEqual, t.String()) Convey("Get value with candidates and default value", func() { So(sec.Key("STRING_404").In("str", []string{"str", "arr", "types"}), ShouldEqual, "str") So(sec.Key("FLOAT64_404").InFloat64(1.25, []float64{1.25, 2.5, 3.75}), ShouldEqual, 1.25) So(sec.Key("INT_404").InInt(10, []int{10, 20, 30}), ShouldEqual, 10) So(sec.Key("INT64_404").InInt64(10, []int64{10, 20, 30}), ShouldEqual, 10) So(sec.Key("UINT_404").InUint(3, []uint{3, 6, 9}), ShouldEqual, 3) So(sec.Key("UINT_404").InUint64(3, []uint64{3, 6, 9}), ShouldEqual, 3) So(sec.Key("TIME_404").InTime(t, []time.Time{time.Now(), time.Now(), time.Now().Add(1 * time.Second)}).String(), ShouldEqual, t.String()) }) }) Convey("Get values in range", func() { sec := cfg.Section("types") So(sec.Key("FLOAT64").RangeFloat64(0, 1, 2), ShouldEqual, 1.25) So(sec.Key("INT").RangeInt(0, 10, 20), ShouldEqual, 10) So(sec.Key("INT").RangeInt64(0, 10, 20), ShouldEqual, 10) minT, err := time.Parse(time.RFC3339, "0001-01-01T01:00:00Z") So(err, ShouldBeNil) midT, err := time.Parse(time.RFC3339, "2013-01-01T01:00:00Z") So(err, ShouldBeNil) maxT, err := time.Parse(time.RFC3339, "9999-01-01T01:00:00Z") So(err, ShouldBeNil) t, err := time.Parse(time.RFC3339, "2015-01-01T20:17:05Z") So(err, ShouldBeNil) So(sec.Key("TIME").RangeTime(t, minT, maxT).String(), ShouldEqual, t.String()) Convey("Get value in range with default value", func() { So(sec.Key("FLOAT64").RangeFloat64(5, 0, 1), ShouldEqual, 5) So(sec.Key("INT").RangeInt(7, 0, 5), ShouldEqual, 7) So(sec.Key("INT").RangeInt64(7, 0, 5), ShouldEqual, 7) So(sec.Key("TIME").RangeTime(t, minT, midT).String(), ShouldEqual, t.String()) }) }) Convey("Get values into slice", func() { sec := cfg.Section("array") So(strings.Join(sec.Key("STRINGS").Strings(","), ","), ShouldEqual, "en,zh,de") So(len(sec.Key("STRINGS_404").Strings(",")), ShouldEqual, 0) vals1 := sec.Key("FLOAT64S").Float64s(",") float64sEqual(vals1, 1.1, 2.2, 3.3) vals2 := sec.Key("INTS").Ints(",") intsEqual(vals2, 1, 2, 3) vals3 := sec.Key("INTS").Int64s(",") int64sEqual(vals3, 1, 2, 3) vals4 := sec.Key("UINTS").Uints(",") uintsEqual(vals4, 1, 2, 3) vals5 := sec.Key("UINTS").Uint64s(",") uint64sEqual(vals5, 1, 2, 3) t, err := time.Parse(time.RFC3339, "2015-01-01T20:17:05Z") So(err, ShouldBeNil) vals6 := sec.Key("TIMES").Times(",") timesEqual(vals6, t, t, t) }) Convey("Get valid values into slice", func() { sec := cfg.Section("array") vals1 := sec.Key("FLOAT64S").ValidFloat64s(",") float64sEqual(vals1, 1.1, 2.2, 3.3) vals2 := sec.Key("INTS").ValidInts(",") intsEqual(vals2, 1, 2, 3) vals3 := sec.Key("INTS").ValidInt64s(",") int64sEqual(vals3, 1, 2, 3) vals4 := sec.Key("UINTS").ValidUints(",") uintsEqual(vals4, 1, 2, 3) vals5 := sec.Key("UINTS").ValidUint64s(",") uint64sEqual(vals5, 1, 2, 3) t, err := time.Parse(time.RFC3339, "2015-01-01T20:17:05Z") So(err, ShouldBeNil) vals6 := sec.Key("TIMES").ValidTimes(",") timesEqual(vals6, t, t, t) }) Convey("Get values one type into slice of another type", func() { sec := cfg.Section("array") vals1 := sec.Key("STRINGS").ValidFloat64s(",") So(vals1, ShouldBeEmpty) vals2 := sec.Key("STRINGS").ValidInts(",") So(vals2, ShouldBeEmpty) vals3 := sec.Key("STRINGS").ValidInt64s(",") So(vals3, ShouldBeEmpty) vals4 := sec.Key("STRINGS").ValidUints(",") So(vals4, ShouldBeEmpty) vals5 := sec.Key("STRINGS").ValidUint64s(",") So(vals5, ShouldBeEmpty) vals6 := sec.Key("STRINGS").ValidTimes(",") So(vals6, ShouldBeEmpty) }) Convey("Get valid values into slice without errors", func() { sec := cfg.Section("array") vals1, err := sec.Key("FLOAT64S").StrictFloat64s(",") So(err, ShouldBeNil) float64sEqual(vals1, 1.1, 2.2, 3.3) vals2, err := sec.Key("INTS").StrictInts(",") So(err, ShouldBeNil) intsEqual(vals2, 1, 2, 3) vals3, err := sec.Key("INTS").StrictInt64s(",") So(err, ShouldBeNil) int64sEqual(vals3, 1, 2, 3) vals4, err := sec.Key("UINTS").StrictUints(",") So(err, ShouldBeNil) uintsEqual(vals4, 1, 2, 3) vals5, err := sec.Key("UINTS").StrictUint64s(",") So(err, ShouldBeNil) uint64sEqual(vals5, 1, 2, 3) t, err := time.Parse(time.RFC3339, "2015-01-01T20:17:05Z") So(err, ShouldBeNil) vals6, err := sec.Key("TIMES").StrictTimes(",") So(err, ShouldBeNil) timesEqual(vals6, t, t, t) }) Convey("Get invalid values into slice", func() { sec := cfg.Section("array") vals1, err := sec.Key("STRINGS").StrictFloat64s(",") So(vals1, ShouldBeEmpty) So(err, ShouldNotBeNil) vals2, err := sec.Key("STRINGS").StrictInts(",") So(vals2, ShouldBeEmpty) So(err, ShouldNotBeNil) vals3, err := sec.Key("STRINGS").StrictInt64s(",") So(vals3, ShouldBeEmpty) So(err, ShouldNotBeNil) vals4, err := sec.Key("STRINGS").StrictUints(",") So(vals4, ShouldBeEmpty) So(err, ShouldNotBeNil) vals5, err := sec.Key("STRINGS").StrictUint64s(",") So(vals5, ShouldBeEmpty) So(err, ShouldNotBeNil) vals6, err := sec.Key("STRINGS").StrictTimes(",") So(vals6, ShouldBeEmpty) So(err, ShouldNotBeNil) }) Convey("Get key hash", func() { cfg.Section("").KeysHash() }) Convey("Set key value", func() { k := cfg.Section("author").Key("NAME") k.SetValue("无闻") So(k.String(), ShouldEqual, "无闻") }) Convey("Get key strings", func() { So(strings.Join(cfg.Section("types").KeyStrings(), ","), ShouldEqual, "STRING,BOOL,BOOL_FALSE,FLOAT64,INT,TIME,DURATION,UINT") }) Convey("Delete a key", func() { cfg.Section("package.sub").DeleteKey("UNUSED_KEY") _, err := cfg.Section("package.sub").GetKey("UNUSED_KEY") So(err, ShouldNotBeNil) }) Convey("Has Key (backwards compatible)", func() { sec := cfg.Section("package.sub") haskey1 := sec.Haskey("UNUSED_KEY") haskey2 := sec.Haskey("CLONE_URL") haskey3 := sec.Haskey("CLONE_URL_NO") So(haskey1, ShouldBeTrue) So(haskey2, ShouldBeTrue) So(haskey3, ShouldBeFalse) }) Convey("Has Key", func() { sec := cfg.Section("package.sub") haskey1 := sec.HasKey("UNUSED_KEY") haskey2 := sec.HasKey("CLONE_URL") haskey3 := sec.HasKey("CLONE_URL_NO") So(haskey1, ShouldBeTrue) So(haskey2, ShouldBeTrue) So(haskey3, ShouldBeFalse) }) Convey("Has Value", func() { sec := cfg.Section("author") hasvalue1 := sec.HasValue("Unknwon") hasvalue2 := sec.HasValue("doc") So(hasvalue1, ShouldBeTrue) So(hasvalue2, ShouldBeFalse) }) Convey("Get section strings", func() { So(strings.Join(cfg.SectionStrings(), ","), ShouldEqual, "DEFAULT,author,package,package.sub,features,types,array,note,comments,advance") }) Convey("Delete a section", func() { cfg.DeleteSection("") So(cfg.SectionStrings()[0], ShouldNotEqual, DEFAULT_SECTION) }) Convey("Create new sections", func() { cfg.NewSections("test", "test2") _, err := cfg.GetSection("test") So(err, ShouldBeNil) _, err = cfg.GetSection("test2") So(err, ShouldBeNil) }) }) Convey("Test getting and setting bad values", t, func() { cfg, err := Load([]byte(_CONF_DATA), "testdata/conf.ini") So(err, ShouldBeNil) So(cfg, ShouldNotBeNil) Convey("Create new key with empty name", func() { k, err := cfg.Section("").NewKey("", "") So(err, ShouldNotBeNil) So(k, ShouldBeNil) }) Convey("Create new section with empty name", func() { s, err := cfg.NewSection("") So(err, ShouldNotBeNil) So(s, ShouldBeNil) }) Convey("Create new sections with empty name", func() { So(cfg.NewSections(""), ShouldNotBeNil) }) Convey("Get section that not exists", func() { s, err := cfg.GetSection("404") So(err, ShouldNotBeNil) So(s, ShouldBeNil) s = cfg.Section("404") So(s, ShouldNotBeNil) }) }) Convey("Test key hash clone", t, func() { cfg, err := Load([]byte(strings.Replace("network=tcp,addr=127.0.0.1:6379,db=4,pool_size=100,idle_timeout=180", ",", "\n", -1))) So(err, ShouldBeNil) for _, v := range cfg.Section("").KeysHash() { So(len(v), ShouldBeGreaterThan, 0) } }) Convey("Key has empty value", t, func() { _conf := `key1= key2= ; comment` cfg, err := Load([]byte(_conf)) So(err, ShouldBeNil) So(cfg.Section("").Key("key1").Value(), ShouldBeEmpty) }) }
func Test_Struct(t *testing.T) { Convey("Map to struct", t, func() { Convey("Map file to struct", func() { ts := new(testStruct) So(MapTo(ts, []byte(_CONF_DATA_STRUCT)), ShouldBeNil) So(ts.Name, ShouldEqual, "Unknwon") So(ts.Age, ShouldEqual, 21) So(ts.Male, ShouldBeTrue) So(ts.Money, ShouldEqual, 1.25) So(ts.Unsigned, ShouldEqual, 3) t, err := time.Parse(time.RFC3339, "1993-10-07T20:17:05Z") So(err, ShouldBeNil) So(ts.Born.String(), ShouldEqual, t.String()) dur, err := time.ParseDuration("2h45m") So(err, ShouldBeNil) So(ts.Time.Seconds(), ShouldEqual, dur.Seconds()) So(strings.Join(ts.Others.Cities, ","), ShouldEqual, "HangZhou,Boston") So(ts.Others.Visits[0].String(), ShouldEqual, t.String()) So(fmt.Sprint(ts.Others.Years), ShouldEqual, "[1993 1994]") So(fmt.Sprint(ts.Others.Numbers), ShouldEqual, "[10010 10086]") So(fmt.Sprint(ts.Others.Ages), ShouldEqual, "[18 19]") So(fmt.Sprint(ts.Others.Populations), ShouldEqual, "[12345678 98765432]") So(fmt.Sprint(ts.Others.Coordinates), ShouldEqual, "[192.168 10.11]") So(ts.Others.Note, ShouldEqual, "Hello world!") So(ts.testEmbeded.GPA, ShouldEqual, 2.8) }) Convey("Map section to struct", func() { foobar := new(fooBar) f, err := Load([]byte(_CONF_DATA_STRUCT)) So(err, ShouldBeNil) So(f.Section("foo.bar").MapTo(foobar), ShouldBeNil) So(foobar.Here, ShouldEqual, "there") So(foobar.When, ShouldEqual, "then") }) Convey("Map to non-pointer struct", func() { cfg, err := Load([]byte(_CONF_DATA_STRUCT)) So(err, ShouldBeNil) So(cfg, ShouldNotBeNil) So(cfg.MapTo(testStruct{}), ShouldNotBeNil) }) Convey("Map to unsupported type", func() { cfg, err := Load([]byte(_CONF_DATA_STRUCT)) So(err, ShouldBeNil) So(cfg, ShouldNotBeNil) cfg.NameMapper = func(raw string) string { if raw == "Byte" { return "NAME" } return raw } So(cfg.MapTo(&unsupport{}), ShouldNotBeNil) So(cfg.MapTo(&unsupport2{}), ShouldNotBeNil) So(cfg.MapTo(&unsupport4{}), ShouldNotBeNil) }) Convey("Map from invalid data source", func() { So(MapTo(&testStruct{}, "hi"), ShouldNotBeNil) }) Convey("Map to wrong types and gain default values", func() { cfg, err := Load([]byte(_INVALID_DATA_CONF_STRUCT)) So(err, ShouldBeNil) t, err := time.Parse(time.RFC3339, "1993-10-07T20:17:05Z") So(err, ShouldBeNil) dv := &defaultValue{"Joe", 10, true, 1.25, t, []string{"HangZhou", "Boston"}} So(cfg.MapTo(dv), ShouldBeNil) So(dv.Name, ShouldEqual, "Joe") So(dv.Age, ShouldEqual, 10) So(dv.Male, ShouldBeTrue) So(dv.Money, ShouldEqual, 1.25) So(dv.Born.String(), ShouldEqual, t.String()) So(strings.Join(dv.Cities, ","), ShouldEqual, "HangZhou,Boston") }) }) Convey("Reflect from struct", t, func() { type Embeded struct { Dates []time.Time `delim:"|"` Places []string Years []int Numbers []int64 Ages []uint Populations []uint64 Coordinates []float64 None []int } type Author struct { Name string `ini:"NAME"` Male bool Age int Height uint GPA float64 Date time.Time NeverMind string `ini:"-"` *Embeded `ini:"infos"` } t, err := time.Parse(time.RFC3339, "1993-10-07T20:17:05Z") So(err, ShouldBeNil) a := &Author{"Unknwon", true, 21, 100, 2.8, t, "", &Embeded{ []time.Time{t, t}, []string{"HangZhou", "Boston"}, []int{1993, 1994}, []int64{10010, 10086}, []uint{18, 19}, []uint64{12345678, 98765432}, []float64{192.168, 10.11}, []int{}, }} cfg := Empty() So(ReflectFrom(cfg, a), ShouldBeNil) var buf bytes.Buffer _, err = cfg.WriteTo(&buf) So(err, ShouldBeNil) So(buf.String(), ShouldEqual, `NAME = Unknwon Male = true Age = 21 Height = 100 GPA = 2.8 Date = 1993-10-07T20:17:05Z [infos] Dates = 1993-10-07T20:17:05Z|1993-10-07T20:17:05Z Places = HangZhou,Boston Years = 1993,1994 Numbers = 10010,10086 Ages = 18,19 Populations = 12345678,98765432 Coordinates = 192.168,10.11 None = `) Convey("Reflect from non-point struct", func() { So(ReflectFrom(cfg, Author{}), ShouldNotBeNil) }) }) }
func TestGrammarIndex(t *testing.T) { // Build a simple BNF grammar description grammar. gb := parser.OpenGrammarBuilder() gb.Terminals("NONTERM", "COLEQ", "PIPE", "IDENTIFIER"). Nonterminals("bnf", "ntdecl", "def", "ntort"). Rule().Lhs("bnf").Rhs("ntdecl"). Rule().Lhs("bnf").Rhs("ntdecl", "bnf"). Rule().Lhs("ntdecl").Rhs("NONTERM", "COLEQ", "def"). Rule().Lhs("ntdecl").Rhs("ntdecl", "PIPE", "def"). Rule().Lhs("def").Rhs("ntort"). Rule().Lhs("def").Rhs("ntort", "def"). Rule().Lhs("ntort").Rhs("IDENTIFIER"). Rule().Lhs("ntort").Rhs("NONTERM"). Rule().Lhs("`*").Rhs("bnf", "`."). Name("simple-bnf") g, err := gb.Build() if err != nil { t.Error(err) } grammar := parser.GetIndexedGrammar(g) fmt.Println("Name: " + grammar.Name()) terms := make([]string, grammar.NumTerminals()) for i, t := range grammar.Terminals() { terms[i] = t.String() } nterms := make([]string, grammar.NumNonterminals()) for i, t := range grammar.Nonterminals() { nterms[i] = t.String() } fmt.Println("Terminals: " + strings.Join(terms, ", ")) fmt.Println("Nonterminals: " + strings.Join(nterms, ", ")) fmt.Println("Productions:") for _, p := range grammar.Productions() { fmt.Println(" " + p.String()) } idx, err := grammar.GetIndex("basic") if err != nil { t.Error() return } basicIndex := idx.(*BasicGrammarIndex) fmt.Println("Basic index type: '" + basicIndex.IndexName() + "'") fmt.Println("Production RHS starts: ") for idx := 0; idx < grammar.NumTerminals(); idx++ { term := grammar.Terminal(idx) starts := basicIndex.RhsStarts(term) if len(starts) == 0 { continue } fmt.Println(" " + term.String() + ":") for _, p := range starts { fmt.Println(" " + p.String()) } } fmt.Println("\nProduction RHS ends: ") for idx := 0; idx < grammar.NumTerminals(); idx++ { term := grammar.Terminal(idx) starts := basicIndex.RhsEnds(term) if len(starts) == 0 { continue } fmt.Println(" " + term.String() + ":") for _, p := range starts { fmt.Println(" " + p.String()) } } fmt.Println("\nProduction RHS contains: ") for idx := 0; idx < grammar.NumTerminals(); idx++ { term := grammar.Terminal(idx) starts := basicIndex.RhsContains(term) if len(starts) == 0 { continue } fmt.Println(" " + term.String() + ":") for _, p := range starts { fmt.Println(" " + p.String()) } } fmt.Println("Grammar class:") idx, err = grammar.GetIndex(GRAMMAR_CLASS_INDEX) if err != nil { t.Error(err) return } gcidx := idx.(*GrammarClassIndex) fmt.Println(" type: " + gcidx.Class().String()) fmt.Println(" regularity: " + gcidx.Regularity().String()) idx, err = grammar.GetIndex(FIRST_FOLLOW_INDEX) if err != nil { t.Error(err) return } ffidx := idx.(*FFIndex) fmt.Println("FIRST(x): ") for _, p := range g.Nonterminals() { fmt.Println(" " + p.String()) for _, k := range ffidx.Firsts(p) { fmt.Println(" " + k.String()) } } fmt.Println("FOLLOW(x): ") for _, p := range g.Nonterminals() { fmt.Println(" " + p.String()) for _, k := range ffidx.Follows(p) { fmt.Println(" " + k.String()) } } for _, p := range g.Terminals() { fmt.Println(" " + p.String()) for _, k := range ffidx.Firsts(p) { fmt.Println(" " + k.String()) } } }
func TestIterator(t *testing.T) { var ts *TripleStore Convey("Given a prepared database", t, func() { tmpDir, _ := ioutil.TempDir(os.TempDir(), "cayley_test") t.Log(tmpDir) defer os.RemoveAll(tmpDir) ok := CreateNewLevelDB(tmpDir) So(ok, ShouldBeTrue) ts = NewTripleStore(tmpDir, nil) ts.AddTripleSet(makeTripleSet()) var it graph.Iterator Convey("Can create an all iterator for nodes", func() { it = ts.GetNodesAllIterator() So(it, ShouldNotBeNil) Convey("Has basics", func() { size, accurate := it.Size() So(size, ShouldBeBetween, 0, 20) So(accurate, ShouldBeFalse) So(it.Type(), ShouldEqual, "all") re_it, ok := it.Optimize() So(ok, ShouldBeFalse) So(re_it, ShouldPointTo, it) }) Convey("Iterates all nodes", func() { expected := []string{ "A", "B", "C", "D", "E", "F", "G", "follows", "status", "cool", "status_graph", } sort.Strings(expected) actual := extractValuesFromIterator(ts, it) sort.Strings(actual) So(actual, ShouldResemble, expected) it.Reset() actual = extractValuesFromIterator(ts, it) sort.Strings(actual) So(actual, ShouldResemble, expected) }) Convey("Contains a couple nodes", func() { So(it.Check(ts.GetIdFor("A")), ShouldBeTrue) So(it.Check(ts.GetIdFor("cool")), ShouldBeTrue) //So(it.Check(ts.GetIdFor("baller")), ShouldBeFalse) }) Reset(func() { it.Reset() }) }) Convey("Can create an all iterator for edges", func() { it := ts.GetTriplesAllIterator() So(it, ShouldNotBeNil) Convey("Has basics", func() { size, accurate := it.Size() So(size, ShouldBeBetween, 0, 20) So(accurate, ShouldBeFalse) So(it.Type(), ShouldEqual, "all") re_it, ok := it.Optimize() So(ok, ShouldBeFalse) So(re_it, ShouldPointTo, it) }) Convey("Iterates an edge", func() { edge_val, _ := it.Next() triple := ts.GetTriple(edge_val) set := makeTripleSet() var string_set []string for _, t := range set { string_set = append(string_set, t.String()) } So(triple.String(), ShouldBeIn, string_set) }) Reset(func() { ts.Close() }) }) }) }
func Test_Struct(t *testing.T) { Convey("Map file to struct", t, func() { ts := new(testStruct) So(MapTo(ts, []byte(_CONF_DATA_STRUCT)), ShouldBeNil) So(ts.Name, ShouldEqual, "Unknwon") So(ts.Age, ShouldEqual, 21) So(ts.Male, ShouldBeTrue) So(ts.Money, ShouldEqual, 1.25) t, err := time.Parse(time.RFC3339, "1993-10-07T20:17:05Z") So(err, ShouldBeNil) So(ts.Born.String(), ShouldEqual, t.String()) So(strings.Join(ts.Others.Cities, ","), ShouldEqual, "HangZhou,Boston") So(ts.Others.Visits[0].String(), ShouldEqual, t.String()) So(ts.Others.Note, ShouldEqual, "Hello world!") So(ts.testEmbeded.GPA, ShouldEqual, 2.8) }) Convey("Map to non-pointer struct", t, func() { cfg, err := Load([]byte(_CONF_DATA_STRUCT)) So(err, ShouldBeNil) So(cfg, ShouldNotBeNil) So(cfg.MapTo(testStruct{}), ShouldNotBeNil) }) Convey("Map to unsupported type", t, func() { cfg, err := Load([]byte(_CONF_DATA_STRUCT)) So(err, ShouldBeNil) So(cfg, ShouldNotBeNil) cfg.NameMapper = func(raw string) string { if raw == "Byte" { return "NAME" } return raw } So(cfg.MapTo(&unsupport{}), ShouldNotBeNil) So(cfg.MapTo(&unsupport2{}), ShouldNotBeNil) So(cfg.MapTo(&unsupport4{}), ShouldNotBeNil) }) Convey("Map from invalid data source", t, func() { So(MapTo(&testStruct{}, "hi"), ShouldNotBeNil) }) Convey("Map to wrong types and gain default values", t, func() { cfg, err := Load([]byte(_INVALID_DATA_CONF_STRUCT)) So(err, ShouldBeNil) t, err := time.Parse(time.RFC3339, "1993-10-07T20:17:05Z") So(err, ShouldBeNil) dv := &defaultValue{"Joe", 10, true, 1.25, t, []string{"HangZhou", "Boston"}} So(cfg.MapTo(dv), ShouldBeNil) So(dv.Name, ShouldEqual, "Joe") So(dv.Age, ShouldEqual, 10) So(dv.Male, ShouldBeTrue) So(dv.Money, ShouldEqual, 1.25) So(dv.Born.String(), ShouldEqual, t.String()) So(strings.Join(dv.Cities, ","), ShouldEqual, "HangZhou,Boston") }) }
func TestTimeCapture(t *testing.T) { Convey("String output should windup in file (instead of os.Stdout) ", t, func() { stdout := os.Stdout defer func() { os.Stdout = stdout }() f, _ := ioutil.TempFile("/tmp", "tc-tests-") fmt.Println(f.Name()) os.Stdout = f t := TimeCapture{} t.Dump() f.Sync() os.Stdout = stdout f.Close() bytes, _ := ioutil.ReadFile(f.Name()) content := string(bytes) str := t.String() So(content, ShouldNotEqual, "") So(content, ShouldEqual, str) }) Convey("Capture time should out a non-zero string", t, func() { delay := 100 * time.Millisecond tc := Capture(func() { <-time.After(delay) }) buf := bytes.NewBufferString("") tc.Out(buf) s := buf.String() So(s, ShouldNotEqual, "") }) Convey("Capture time of function should take >= delayed time", t, func() { delay := 200 * time.Millisecond tc := Capture(func() { <-time.After(delay) }) So(tc.Elapsed(), ShouldBeGreaterThanOrEqualTo, delay) }) Convey("A started delta should have a start >= to now", t, func() { d := &Delta{} t := time.Now().UnixNano() d.Start() So(d.start, ShouldBeGreaterThanOrEqualTo, t) So(d.end, ShouldEqual, 0) So(d.Elapsed(), ShouldBeGreaterThanOrEqualTo, 0) }) Convey("Should only be able to call Stop() once and capture that timestamp", t, func() { d := &Delta{} d.Start() <-time.NewTimer(50 * time.Millisecond).C d.Stop() originalStop := d.end <-time.NewTimer(50 * time.Millisecond).C d.Stop() So(d.isStarted, ShouldBeTrue) So(d.isStopped, ShouldBeTrue) So(d.end, ShouldEqual, originalStop) }) Convey("Should only be able to call Start() once and capture that timestamp", t, func() { d := &Delta{} d.Start() originalStart := d.start <-time.NewTimer(50 * time.Millisecond).C d.Start() So(d.isStopped, ShouldBeFalse) So(d.isStarted, ShouldBeTrue) So(d.start, ShouldEqual, originalStart) }) Convey("Calling Elapsed() should stop the timer", t, func() { d := &Delta{} d.Elapsed() So(d.isStopped, ShouldBeTrue) }) Convey("New Delta should have ellapsed time of 0", t, func() { d := &Delta{} So(d.start, ShouldEqual, 0) So(d.end, ShouldEqual, 0) So(d.isStarted, ShouldBeFalse) So(d.isStopped, ShouldBeFalse) So(d.Diff(), ShouldEqual, 0) So(int64(d.Elapsed()), ShouldBeGreaterThan, 0) }) }