func TestJSCodeBSONToJSON(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Converting BSON Javascript code to JSON", t, func() { Convey("should produce a json.Javascript", func() { Convey("without scope if the scope for the BSON Javascript code is nil", func() { _jObj, err := ConvertBSONValueToJSON(bson.JavaScript{"function() { return null; }", nil}) So(err, ShouldBeNil) jObj, ok := _jObj.(json.JavaScript) So(ok, ShouldBeTrue) So(jObj, ShouldResemble, json.JavaScript{"function() { return null; }", nil}) }) Convey("with scope if the scope for the BSON Javascript code is non-nil", func() { _jObj, err := ConvertBSONValueToJSON(bson.JavaScript{"function() { return x; }", bson.M{"x": 2}}) So(err, ShouldBeNil) jObj, ok := _jObj.(json.JavaScript) So(ok, ShouldBeTrue) So(jObj.Scope.(bson.M)["x"], ShouldEqual, 2) So(jObj.Code, ShouldEqual, "function() { return x; }") }) }) }) }
func TestGetUpsertValue(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Given a field and a BSON document, on calling getUpsertValue", t, func() { Convey("the value of the key should be correct for unnested "+ "documents", func() { bsonDocument := bson.M{"a": 3} So(getUpsertValue("a", bsonDocument), ShouldEqual, 3) }) Convey("the value of the key should be correct for nested "+ "document fields", func() { bsonDocument := bson.M{"a": bson.M{"b": 4}} So(getUpsertValue("a.b", bsonDocument), ShouldEqual, 4) }) Convey("the value of the key should be nil for unnested document "+ "fields that do not exist", func() { bsonDocument := bson.M{"a": 4} So(getUpsertValue("c", bsonDocument), ShouldBeNil) }) Convey("the value of the key should be nil for nested document "+ "fields that do not exist", func() { bsonDocument := bson.M{"a": bson.M{"b": 4}} So(getUpsertValue("a.c", bsonDocument), ShouldBeNil) }) Convey("the value of the key should be nil for nil document"+ "values", func() { So(getUpsertValue("a", bson.M{"a": nil}), ShouldBeNil) }) }) }
func TestCreateIntentsForDB(t *testing.T) { // This tests creates intents based on the test file tree: // db1 // db1/baddir // db1/baddir/out.bson // db1/c1.bson // db1/c1.metadata.json // db1/c2.bson // db1/c3.bson // db1/c3.metadata.json var mr *MongoRestore var buff bytes.Buffer testutil.VerifyTestType(t, testutil.UnitTestType) Convey("With a test MongoRestore", t, func() { mr = newMongoRestore() log.SetWriter(&buff) Convey("running CreateIntentsForDB should succeed", func() { ddl, err := newActualPath("testdata/testdirs/db1") So(err, ShouldBeNil) err = mr.CreateIntentsForDB("myDB", ddl) So(err, ShouldBeNil) mr.manager.Finalize(intents.Legacy) Convey("and reading the intents should show alphabetical order", func() { i0 := mr.manager.Pop() So(i0.C, ShouldEqual, "c1") i1 := mr.manager.Pop() So(i1.C, ShouldEqual, "c2") i2 := mr.manager.Pop() So(i2.C, ShouldEqual, "c3") i3 := mr.manager.Pop() So(i3, ShouldBeNil) Convey("and all intents should have the supplied db name", func() { So(i0.DB, ShouldEqual, "myDB") So(i1.DB, ShouldEqual, "myDB") So(i2.DB, ShouldEqual, "myDB") }) Convey("with all the proper metadata + bson merges", func() { So(i0.Location, ShouldNotEqual, "") So(i0.MetadataLocation, ShouldNotEqual, "") So(i1.Location, ShouldNotEqual, "") So(i1.MetadataLocation, ShouldEqual, "") //no metadata for this file So(i2.Location, ShouldNotEqual, "") So(i2.MetadataLocation, ShouldNotEqual, "") Convey("and skipped files all present in the logs", func() { logs := buff.String() So(strings.Contains(logs, "baddir"), ShouldEqual, true) }) }) }) }) }) }
func TestKerberos(t *testing.T) { testutil.VerifyTestType(t, testutil.KerberosTestType) Convey("Should be able to run mongoexport with Kerberos auth", t, func() { opts, err := testutil.GetKerberosOptions() So(err, ShouldBeNil) sessionProvider, err := db.NewSessionProvider(*opts) So(err, ShouldBeNil) export := MongoExport{ ToolOptions: *opts, OutputOpts: &OutputFormatOptions{}, InputOpts: &InputOptions{}, SessionProvider: sessionProvider, } var out bytes.Buffer num, err := export.exportInternal(&out) So(err, ShouldBeNil) So(num, ShouldEqual, 1) outputLines := strings.Split(strings.TrimSpace(out.String()), "\n") So(len(outputLines), ShouldEqual, 1) So(outputLines[0], ShouldEqual, "{\"_id\":{\"$oid\":\"528fb35afb3a8030e2f643c3\"},"+ "\"authenticated\":\"yeah\",\"kerberos\":true}") }) }
func TestMongoDumpValidateOptions(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("With a MongoDump instance", t, func() { md := simpleMongoDumpInstance() Convey("we cannot dump a collection when a database specified", func() { md.ToolOptions.Namespace.Collection = "some_collection" md.ToolOptions.Namespace.DB = "" err := md.Init() So(err, ShouldNotBeNil) So(err.Error(), ShouldContainSubstring, "cannot dump a collection without a specified database") }) Convey("we have to specify a collection name if using a query", func() { md.ToolOptions.Namespace.Collection = "" md.OutputOptions.Out = "" md.InputOptions.Query = "{_id:\"\"}" err := md.Init() So(err, ShouldNotBeNil) So(err.Error(), ShouldContainSubstring, "cannot dump using a query without a specified collection") }) }) }
func TestJSONArray(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("With a JSON export output in array mode", t, func() { out := &bytes.Buffer{} Convey("exporting a bunch of documents should produce valid json", func() { jsonExporter := NewJSONExportOutput(true, false, out) err := jsonExporter.WriteHeader() So(err, ShouldBeNil) // Export a few docs of various types testObjs := []interface{}{bson.NewObjectId(), "asd", 12345, 3.14159, bson.M{"A": 1}} for _, obj := range testObjs { err = jsonExporter.ExportDocument(bson.M{"_id": obj}) So(err, ShouldBeNil) } err = jsonExporter.WriteFooter() So(err, ShouldBeNil) // Unmarshal the whole thing, it should be valid json fromJSON := []map[string]interface{}{} err = json.Unmarshal(out.Bytes(), &fromJSON) So(err, ShouldBeNil) So(len(fromJSON), ShouldEqual, len(testObjs)) }) Reset(func() { out.Reset() }) }) }
func TestWriteJSON(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("With a JSON export output", t, func() { out := &bytes.Buffer{} Convey("Special types should serialize as extended JSON", func() { Convey("ObjectId should have an extended JSON format", func() { jsonExporter := NewJSONExportOutput(false, false, out) objId := bson.NewObjectId() err := jsonExporter.WriteHeader() So(err, ShouldBeNil) err = jsonExporter.ExportDocument(bson.M{"_id": objId}) So(err, ShouldBeNil) err = jsonExporter.WriteFooter() So(err, ShouldBeNil) So(out.String(), ShouldEqual, `{"_id":{"$oid":"`+objId.Hex()+`"}}`+"\n") }) Reset(func() { out.Reset() }) }) }) }
func TestRemoveBlankFields(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Given an unordered BSON document", t, func() { Convey("the same document should be returned if there are no blanks", func() { bsonDocument := bson.D{bson.DocElem{"a", 3}, bson.DocElem{"b", "hello"}} So(removeBlankFields(bsonDocument), ShouldResemble, bsonDocument) }) Convey("a new document without blanks should be returned if there are "+ " blanks", func() { bsonDocument := bson.D{ bson.DocElem{"a", 0}, bson.DocElem{"b", ""}, bson.DocElem{"c", ""}, bson.DocElem{"d", &bson.D{ bson.DocElem{"a", ""}, bson.DocElem{"b", ""}, }}, bson.DocElem{"e", &bson.D{ bson.DocElem{"a", ""}, bson.DocElem{"b", 1}, }}, } expectedDocument := bson.D{ bson.DocElem{"a", 0}, bson.DocElem{"e", bson.D{ bson.DocElem{"b", 1}, }}, } So(removeBlankFields(bsonDocument), ShouldResemble, expectedDocument) }) }) }
func TestFilterIngestError(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Given a boolean 'stopOnError' and an error...", t, func() { Convey("an error should be returned if stopOnError is true the err is not nil", func() { So(filterIngestError(true, fmt.Errorf("")), ShouldNotBeNil) }) Convey("errLostConnection should be returned if stopOnError is true the err is io.EOF", func() { So(filterIngestError(true, io.EOF), ShouldEqual, db.ErrLostConnection) }) Convey("no error should be returned if stopOnError is false the err is not nil", func() { So(filterIngestError(false, fmt.Errorf("")), ShouldBeNil) }) Convey("no error should be returned if stopOnError is false the err is nil", func() { So(filterIngestError(false, nil), ShouldBeNil) }) Convey("no error should be returned if stopOnError is true the err is nil", func() { So(filterIngestError(true, nil), ShouldBeNil) }) }) }
func TestGetSourceReader(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Given a mongoimport instance, on calling getSourceReader", t, func() { Convey("an error should be thrown if the given file referenced by "+ "the reader does not exist", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.File = "/path/to/input/file/dot/input.txt" imp.InputOptions.Type = CSV imp.ToolOptions.Namespace.Collection = "" _, _, err = imp.getSourceReader() So(err, ShouldNotBeNil) }) Convey("no error should be thrown if the file exists", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.File = "testdata/test_array.json" imp.InputOptions.Type = JSON _, _, err = imp.getSourceReader() So(err, ShouldBeNil) }) Convey("no error should be thrown if stdin is used", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.File = "" _, _, err = imp.getSourceReader() So(err, ShouldBeNil) }) }) }
func TestFailpointParsing(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("With test args", t, func() { args := "foo=bar,baz,biz=,=a" ParseFailpoints(args) So(Enabled("foo"), ShouldBeTrue) So(Enabled("baz"), ShouldBeTrue) So(Enabled("biz"), ShouldBeTrue) So(Enabled(""), ShouldBeTrue) So(Enabled("bar"), ShouldBeFalse) var val string var ok bool val, ok = Get("foo") So(val, ShouldEqual, "bar") So(ok, ShouldBeTrue) val, ok = Get("baz") So(val, ShouldEqual, "") So(ok, ShouldBeTrue) val, ok = Get("biz") So(val, ShouldEqual, "") So(ok, ShouldBeTrue) val, ok = Get("") So(val, ShouldEqual, "a") So(ok, ShouldBeTrue) val, ok = Get("bar") So(ok, ShouldBeFalse) }) }
func TestBufferPoolRecycling(t *testing.T) { testutil.VerifyTestType(t, "unit") Convey("With a BufferPool of size 1", t, func() { bp := NewBufferPool(1) So(bp, ShouldNotBeNil) Convey("get a buffer from the pool and then return it", func() { a := bp.Get() So(len(a), ShouldEqual, 1) a[0] = 'a' bp.Put(a) Convey("so now getting a buffer should recycle the previous buffer", func() { newA := bp.Get() So(newA[0], ShouldEqual, 'a') newA[0] = 'X' So(a[0], ShouldEqual, 'X') //assure both point to the same thing Convey("but getting a second new buffer should be clean", func() { newB := bp.Get() So(newB[0], ShouldNotEqual, 'a') So(newB[0], ShouldNotEqual, 'X') }) }) }) }) }
func TestDBCounterCollectionSorting(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("With a dbCounter and an unordered collection of intents", t, func() { dbc := &dbCounter{ collections: []*Intent{ &Intent{Size: 100}, &Intent{Size: 1000}, &Intent{Size: 1}, &Intent{Size: 10}, }, } Convey("popping the sorted intents should return in decreasing BSONSize", func() { dbc.SortCollectionsBySize() So(dbc.PopIntent().Size, ShouldEqual, 1000) So(dbc.PopIntent().Size, ShouldEqual, 100) So(dbc.PopIntent().Size, ShouldEqual, 10) So(dbc.PopIntent().Size, ShouldEqual, 1) So(dbc.PopIntent(), ShouldBeNil) So(dbc.PopIntent(), ShouldBeNil) }) }) }
func TestNumberConverter(t *testing.T) { testutil.VerifyTestType(t, "unit") Convey("With a number converter for float32", t, func() { floatConverter := newNumberConverter(reflect.TypeOf(float32(0))) Convey("numeric values should be convertable", func() { out, err := floatConverter(21) So(err, ShouldEqual, nil) So(out, ShouldEqual, 21.0) out, err = floatConverter(uint64(21)) So(err, ShouldEqual, nil) So(out, ShouldEqual, 21.0) out, err = floatConverter(float64(27.52)) So(err, ShouldEqual, nil) So(out, ShouldEqual, 27.52) }) Convey("non-numeric values should fail", func() { _, err := floatConverter("I AM A STRING") So(err, ShouldNotBeNil) _, err = floatConverter(struct{ int }{12}) So(err, ShouldNotBeNil) _, err = floatConverter(nil) So(err, ShouldNotBeNil) }) }) }
func TestKerberos(t *testing.T) { testutil.VerifyTestType(t, testutil.KerberosTestType) Convey("Should be able to run mongoexport with Kerberos auth", t, func() { opts, err := testutil.GetKerberosOptions() So(err, ShouldBeNil) sessionProvider, err := db.NewSessionProvider(*opts) So(err, ShouldBeNil) export := MongoExport{ ToolOptions: *opts, OutputOpts: &OutputFormatOptions{}, InputOpts: &InputOptions{}, SessionProvider: sessionProvider, } var out bytes.Buffer num, err := export.exportInternal(&out) So(err, ShouldBeNil) So(num, ShouldEqual, 1) outputLines := strings.Split(strings.TrimSpace(out.String()), "\n") So(len(outputLines), ShouldEqual, 1) outMap := map[string]interface{}{} So(json.Unmarshal([]byte(outputLines[0]), &outMap), ShouldBeNil) So(outMap["kerberos"], ShouldEqual, true) So(outMap["authenticated"], ShouldEqual, "yeah") So(outMap["_id"].(map[string]interface{})["$oid"], ShouldEqual, "528fb35afb3a8030e2f643c3") }) }
func TestParseConnectionString(t *testing.T) { testutil.VerifyTestType(t, "unit") Convey("When extracting the replica set and hosts from a connection"+ " url", t, func() { Convey("an empty url should lead to an empty replica set name"+ " and hosts slice", func() { hosts, setName := ParseConnectionString("") So(hosts, ShouldResemble, []string{""}) So(setName, ShouldEqual, "") }) Convey("a url not specifying a replica set name should lead to"+ " an empty replica set name", func() { hosts, setName := ParseConnectionString("host1,host2") So(hosts, ShouldResemble, []string{"host1", "host2"}) So(setName, ShouldEqual, "") }) Convey("a url specifying a replica set name should lead to that name"+ " being returned", func() { hosts, setName := ParseConnectionString("foo/host1,host2") So(hosts, ShouldResemble, []string{"host1", "host2"}) So(setName, ShouldEqual, "foo") }) }) }
func TestUInt32Converter(t *testing.T) { testutil.VerifyTestType(t, "unit") Convey("With a series of test values, conversions should pass", t, func() { out, err := ToUInt32(int64(99)) So(err, ShouldEqual, nil) So(out, ShouldEqual, uint32(99)) out, err = ToUInt32(int32(99)) So(err, ShouldEqual, nil) So(out, ShouldEqual, uint32(99)) out, err = ToUInt32(float32(99)) So(err, ShouldEqual, nil) So(out, ShouldEqual, uint32(99)) out, err = ToUInt32(float64(99)) So(err, ShouldEqual, nil) So(out, ShouldEqual, uint32(99)) out, err = ToUInt32(uint64(99)) So(err, ShouldEqual, nil) So(out, ShouldEqual, uint32(99)) out, err = ToUInt32(uint32(99)) So(err, ShouldEqual, nil) So(out, ShouldEqual, uint32(99)) Convey("but non-numeric inputs will fail", func() { _, err = ToUInt32(nil) So(err, ShouldNotBeNil) _, err = ToUInt32("string") So(err, ShouldNotBeNil) _, err = ToUInt32([]byte{1, 2, 3, 4}) So(err, ShouldNotBeNil) }) }) }
func TestCreateConnectionAddrs(t *testing.T) { testutil.VerifyTestType(t, "unit") Convey("When creating the slice of connection addresses", t, func() { Convey("if no port is specified, the addresses should all appear"+ " unmodified in the result", func() { addrs := CreateConnectionAddrs("host1,host2", "") So(addrs, ShouldResemble, []string{"host1", "host2"}) }) Convey("if a port is specified, it should be appended to each host"+ " from the host connection string", func() { addrs := CreateConnectionAddrs("host1,host2", "20000") So(addrs, ShouldResemble, []string{"host1:20000", "host2:20000"}) }) }) }
func TestParseHost(t *testing.T) { testutil.VerifyTestType(t, "unit") Convey("When parsing a host string into the contained"+ " addresses", t, func() { Convey("a string with a single hostname should return a slice of just"+ " the hostname", func() { addrs := parseHost("localhost") So(addrs, ShouldResemble, []string{"localhost"}) }) Convey("a string with multiple hostnames should return a slice of"+ " all of them", func() { addrs := parseHost("host1,host2,host3") So(addrs, ShouldResemble, []string{"host1", "host2", "host3"}) }) Convey("a string with multiple hostnames and a replica set should"+ " return a slice of all the host names", func() { addrs := parseHost("foo/host1,host2,host3") So(addrs, ShouldResemble, []string{"host1", "host2", "host3"}) }) }) }
func TestValidateFields(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Given an import input, in validating the headers", t, func() { Convey("if the fields contain '..', an error should be thrown", func() { So(validateFields([]string{"a..a"}), ShouldNotBeNil) }) Convey("if the fields start/end in a '.', an error should be thrown", func() { So(validateFields([]string{".a"}), ShouldNotBeNil) So(validateFields([]string{"a."}), ShouldNotBeNil) }) Convey("if the fields start in a '$', an error should be thrown", func() { So(validateFields([]string{"$.a"}), ShouldNotBeNil) So(validateFields([]string{"$"}), ShouldNotBeNil) So(validateFields([]string{"$a"}), ShouldNotBeNil) So(validateFields([]string{"a$a"}), ShouldBeNil) }) Convey("if the fields collide, an error should be thrown", func() { So(validateFields([]string{"a", "a.a"}), ShouldNotBeNil) So(validateFields([]string{"a", "a.ba", "b.a"}), ShouldNotBeNil) So(validateFields([]string{"a", "a.ba", "b.a"}), ShouldNotBeNil) So(validateFields([]string{"a", "a.b.c"}), ShouldNotBeNil) }) Convey("if the fields don't collide, no error should be thrown", func() { So(validateFields([]string{"a", "aa"}), ShouldBeNil) So(validateFields([]string{"a", "aa", "b.a", "b.c"}), ShouldBeNil) So(validateFields([]string{"a", "ba", "ab", "b.a"}), ShouldBeNil) So(validateFields([]string{"a", "ba", "ab", "b.a", "b.c.d"}), ShouldBeNil) So(validateFields([]string{"a", "ab.c"}), ShouldBeNil) }) Convey("if the fields contain the same keys, an error should be thrown", func() { So(validateFields([]string{"a", "ba", "a"}), ShouldNotBeNil) }) }) }
func TestRunCommand(t *testing.T) { testutil.VerifyTestType(t, "db") Convey("When running a db command against a live mongod", t, func() { Convey("the specified command should be run and unmarshalled into the"+ " provided struct", func() { opts := options.ToolOptions{ Connection: &options.Connection{}, SSL: &options.SSL{}, Auth: &options.Auth{}, } provider, err := InitSessionProvider(opts) So(err, ShouldBeNil) cmd := &listDatabasesCommand{} So(provider.RunCommand("admin", cmd), ShouldBeNil) So(cmd.Databases, ShouldNotBeNil) So(cmd.Ok, ShouldBeTrue) }) }) }
func TestTokensToBSON(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Given an slice of fields and tokens to convert to BSON", t, func() { Convey("the expected ordered BSON should be produced for the fields/tokens given", func() { fields := []string{"a", "b", "c"} tokens := []string{"1", "2", "hello"} expectedDocument := bson.D{ bson.DocElem{"a", 1}, bson.DocElem{"b", 2}, bson.DocElem{"c", "hello"}, } bsonD, err := tokensToBSON(fields, tokens, uint64(0)) So(err, ShouldBeNil) So(bsonD, ShouldResemble, expectedDocument) }) Convey("if there are more tokens than fields, additional fields should be prefixed"+ " with 'fields' and an index indicating the header number", func() { fields := []string{"a", "b", "c"} tokens := []string{"1", "2", "hello", "mongodb", "user"} expectedDocument := bson.D{ bson.DocElem{"a", 1}, bson.DocElem{"b", 2}, bson.DocElem{"c", "hello"}, bson.DocElem{"field3", "mongodb"}, bson.DocElem{"field4", "user"}, } bsonD, err := tokensToBSON(fields, tokens, uint64(0)) So(err, ShouldBeNil) So(bsonD, ShouldResemble, expectedDocument) }) Convey("an error should be thrown if duplicate headers are found", func() { fields := []string{"a", "b", "field3"} tokens := []string{"1", "2", "hello", "mongodb", "user"} _, err := tokensToBSON(fields, tokens, uint64(0)) So(err, ShouldNotBeNil) }) Convey("fields with nested values should be set appropriately", func() { fields := []string{"a", "b", "c.a"} tokens := []string{"1", "2", "hello"} expectedDocument := bson.D{ bson.DocElem{"a", 1}, bson.DocElem{"b", 2}, bson.DocElem{"c", bson.D{ bson.DocElem{"a", "hello"}, }}, } bsonD, err := tokensToBSON(fields, tokens, uint64(0)) So(err, ShouldBeNil) So(expectedDocument[0].Name, ShouldResemble, bsonD[0].Name) So(expectedDocument[0].Value, ShouldResemble, bsonD[0].Value) So(expectedDocument[1].Name, ShouldResemble, bsonD[1].Name) So(expectedDocument[1].Value, ShouldResemble, bsonD[1].Value) So(expectedDocument[2].Name, ShouldResemble, bsonD[2].Name) So(expectedDocument[2].Value, ShouldResemble, *bsonD[2].Value.(*bson.D)) }) }) }
func TestWriteCSV(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("With a CSV export output", t, func() { fields := []string{"_id", "x", " y", "z.1.a"} out := &bytes.Buffer{} Convey("Headers should be written correctly", func() { csvExporter := NewCSVExportOutput(fields, false, out) err := csvExporter.WriteHeader() So(err, ShouldBeNil) csvExporter.ExportDocument(bson.D{{"_id", "12345"}}) csvExporter.WriteFooter() csvExporter.Flush() rec, err := csv.NewReader(strings.NewReader(out.String())).Read() So(err, ShouldBeNil) So(rec, ShouldResemble, []string{"_id", "x", " y", "z.1.a"}) }) Convey("Headers should not be written", func() { csvExporter := NewCSVExportOutput(fields, true, out) err := csvExporter.WriteHeader() So(err, ShouldBeNil) csvExporter.ExportDocument(bson.D{{"_id", "12345"}}) csvExporter.WriteFooter() csvExporter.Flush() rec, err := csv.NewReader(strings.NewReader(out.String())).Read() So(err, ShouldBeNil) So(rec, ShouldResemble, []string{"12345", "", "", ""}) }) Convey("Exported document with missing fields should print as blank", func() { csvExporter := NewCSVExportOutput(fields, true, out) csvExporter.ExportDocument(bson.D{{"_id", "12345"}}) csvExporter.WriteFooter() csvExporter.Flush() rec, err := csv.NewReader(strings.NewReader(out.String())).Read() So(err, ShouldBeNil) So(rec, ShouldResemble, []string{"12345", "", "", ""}) }) Convey("Exported document with index into nested objects should print correctly", func() { csvExporter := NewCSVExportOutput(fields, true, out) z := []interface{}{"x", bson.D{{"a", "T"}, {"B", 1}}} csvExporter.ExportDocument(bson.D{{Name: "z", Value: z}}) csvExporter.WriteFooter() csvExporter.Flush() rec, err := csv.NewReader(strings.NewReader(out.String())).Read() So(err, ShouldBeNil) So(rec, ShouldResemble, []string{"", "", "", "T"}) }) Reset(func() { out.Reset() }) }) }
func TestTypedHeaderParser(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Using 'zip.string(),number.double(),foo.auto()'", t, func() { var headers = []string{"zip.string()", "number.double()", "foo.auto()", `bar.date(January 2\, \(2006\))`} var colSpecs []ColumnSpec var err error Convey("with parse grace: auto", func() { colSpecs, err = ParseTypedHeaders(headers, pgAutoCast) So(colSpecs, ShouldResemble, []ColumnSpec{ {"zip", new(FieldStringParser), pgAutoCast, "string"}, {"number", new(FieldDoubleParser), pgAutoCast, "double"}, {"foo", new(FieldAutoParser), pgAutoCast, "auto"}, {"bar", &FieldDateParser{"January 2, (2006)"}, pgAutoCast, "date"}, }) So(err, ShouldBeNil) }) Convey("with parse grace: skipRow", func() { colSpecs, err = ParseTypedHeaders(headers, pgSkipRow) So(colSpecs, ShouldResemble, []ColumnSpec{ {"zip", new(FieldStringParser), pgSkipRow, "string"}, {"number", new(FieldDoubleParser), pgSkipRow, "double"}, {"foo", new(FieldAutoParser), pgSkipRow, "auto"}, {"bar", &FieldDateParser{"January 2, (2006)"}, pgSkipRow, "date"}, }) So(err, ShouldBeNil) }) }) Convey("Using various bad headers", t, func() { var err error Convey("with non-empty arguments for types that don't want them", func() { _, err = ParseTypedHeader("zip.string(blah)", pgAutoCast) So(err, ShouldNotBeNil) _, err = ParseTypedHeader("zip.string(0)", pgAutoCast) So(err, ShouldNotBeNil) _, err = ParseTypedHeader("zip.int32(0)", pgAutoCast) So(err, ShouldNotBeNil) _, err = ParseTypedHeader("zip.int64(0)", pgAutoCast) So(err, ShouldNotBeNil) _, err = ParseTypedHeader("zip.double(0)", pgAutoCast) So(err, ShouldNotBeNil) _, err = ParseTypedHeader("zip.auto(0)", pgAutoCast) So(err, ShouldNotBeNil) }) Convey("with bad arguments for the binary type", func() { _, err = ParseTypedHeader("zip.binary(blah)", pgAutoCast) So(err, ShouldNotBeNil) _, err = ParseTypedHeader("zip.binary(binary)", pgAutoCast) So(err, ShouldNotBeNil) _, err = ParseTypedHeader("zip.binary(decimal)", pgAutoCast) So(err, ShouldNotBeNil) }) }) }
func TestFieldSelect(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Using makeFieldSelector should return correct projection doc", t, func() { So(makeFieldSelector("a,b"), ShouldResemble, bson.M{"_id": 1, "a": 1, "b": 1}) So(makeFieldSelector(""), ShouldResemble, bson.M{"_id": 1}) So(makeFieldSelector("x,foo.baz"), ShouldResemble, bson.M{"_id": 1, "foo": 1, "x": 1}) }) }
func TestServerStatusCommandDiff(t *testing.T) { testutil.VerifyTestType(t, "unit") Convey("When diffing two ServerStatus commands", t, func() { }) }
func TestServerStatusDiffToRows(t *testing.T) { testutil.VerifyTestType(t, "unit") Convey("When converting a ServerStatusDiff to rows to be "+ " printed", t, func() { }) }
func TestUnknownBSONTypeToJSON(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Converting an unknown BSON type to JSON", t, func() { Convey("should produce an error", func() { _, err := ConvertBSONValueToJSON(func() {}) So(err, ShouldNotBeNil) }) }) }
func TestArraysBSONToJSON(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Converting BSON arrays to JSON arrays", t, func() { Convey("should work for empty arrays", func() { jArr, err := ConvertBSONValueToJSON([]interface{}{}) So(err, ShouldBeNil) So(jArr, ShouldResemble, []interface{}{}) }) Convey("should work for one-level deep arrays", func() { objId := bson.NewObjectId() bsonArr := []interface{}{objId, 28, 0.999, "plain"} _jArr, err := ConvertBSONValueToJSON(bsonArr) So(err, ShouldBeNil) jArr, ok := _jArr.([]interface{}) So(ok, ShouldBeTrue) So(len(jArr), ShouldEqual, 4) So(jArr[0], ShouldEqual, json.ObjectId(objId.Hex())) So(jArr[1], ShouldEqual, 28) So(jArr[2], ShouldEqual, 0.999) So(jArr[3], ShouldEqual, "plain") }) Convey("should work for arrays with embedded objects", func() { bsonObj := []interface{}{ 80, bson.M{ "a": int64(20), "b": bson.M{ "c": bson.RegEx{Pattern: "hi", Options: "i"}, }, }, } __jObj, err := ConvertBSONValueToJSON(bsonObj) So(err, ShouldBeNil) _jObj, ok := __jObj.([]interface{}) So(ok, ShouldBeTrue) jObj, ok := _jObj[1].(bson.M) So(ok, ShouldBeTrue) So(len(jObj), ShouldEqual, 2) So(jObj["a"], ShouldEqual, json.NumberLong(20)) jjObj, ok := jObj["b"].(bson.M) So(ok, ShouldBeTrue) So(jjObj["c"], ShouldResemble, json.RegExp{"hi", "i"}) So(jjObj["c"], ShouldNotResemble, json.RegExp{"i", "hi"}) }) }) }
func TestTimestampStringParsing(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Testing some possible timestamp strings:", t, func() { Convey("123:456 [should pass]", func() { ts, err := ParseTimestampFlag("123:456") So(err, ShouldBeNil) So(ts, ShouldEqual, (int64(123)<<32 | int64(456))) }) Convey("123 [should pass]", func() { ts, err := ParseTimestampFlag("123") So(err, ShouldBeNil) So(ts, ShouldEqual, int64(123)<<32) }) Convey("123: [should pass]", func() { ts, err := ParseTimestampFlag("123:") So(err, ShouldBeNil) So(ts, ShouldEqual, int64(123)<<32) }) Convey("123.123 [should fail]", func() { ts, err := ParseTimestampFlag("123.123") So(err, ShouldNotBeNil) So(ts, ShouldEqual, 0) }) Convey(": [should fail]", func() { ts, err := ParseTimestampFlag(":") So(err, ShouldNotBeNil) So(ts, ShouldEqual, 0) }) Convey("1:1:1 [should fail]", func() { ts, err := ParseTimestampFlag("1:1:1") So(err, ShouldNotBeNil) So(ts, ShouldEqual, 0) }) Convey("cats [should fail]", func() { ts, err := ParseTimestampFlag("cats") So(err, ShouldNotBeNil) So(ts, ShouldEqual, 0) }) Convey("[empty string] [should fail]", func() { ts, err := ParseTimestampFlag("") So(err, ShouldNotBeNil) So(ts, ShouldEqual, 0) }) }) }