diff --git a/mongoimport/mongoimport_test.go b/mongoimport/mongoimport_test.go index 727455d63..51db3411d 100644 --- a/mongoimport/mongoimport_test.go +++ b/mongoimport/mongoimport_test.go @@ -183,395 +183,476 @@ func getImportWithArgs(additionalArgs ...string) (*MongoImport, error) { func TestSplitInlineHeader(t *testing.T) { testtype.SkipUnlessTestType(t, testtype.UnitTestType) - Convey("handle normal, untyped headers", t, func() { - fields := []string{"foo.bar", "baz", "boo"} - header := strings.Join(fields, ",") - Convey("with '"+header+"'", func() { - So(splitInlineHeader(header), ShouldResemble, fields) - }) - }) - Convey("handle typed headers", t, func() { - fields := []string{"foo.bar.string()", "baz.date(January 2 2006)", "boo.binary(hex)"} - header := strings.Join(fields, ",") - Convey("with '"+header+"'", func() { - So(splitInlineHeader(header), ShouldResemble, fields) - }) - }) - Convey("handle typed headers that include commas", t, func() { - fields := []string{"foo.bar.date(,,,,)", "baz.date(January 2, 2006)", "boo.binary(hex)"} - header := strings.Join(fields, ",") - Convey("with '"+header+"'", func() { - So(splitInlineHeader(header), ShouldResemble, fields) - }) - }) + + cases := []struct { + name string + fields []string + }{ + {"handle normal, untyped headers", []string{"foo.bar", "baz", "boo"}}, + { + "handle typed headers", + []string{"foo.bar.string()", "baz.date(January 2 2006)", "boo.binary(hex)"}, + }, + { + "handle typed headers that include commas", + []string{"foo.bar.date(,,,,)", "baz.date(January 2, 2006)", "boo.binary(hex)"}, + }, + } + + for _, tc := range cases { + header := strings.Join(tc.fields, ",") + assert.Equal(t, tc.fields, splitInlineHeader(header), "should %s", tc.name) + } } func TestMongoImportValidateSettings(t *testing.T) { testtype.SkipUnlessTestType(t, testtype.UnitTestType) - Convey("Given a mongoimport instance for validation, ", t, func() { - Convey("an error should be thrown if no collection is given", func() { - imp := NewMockMongoImport() - imp.ToolOptions.DB = "" - imp.ToolOptions.Collection = "" - So(imp.validateSettings(), ShouldNotBeNil) - }) - - Convey("an error should be thrown if an invalid type is given", func() { - imp := NewMockMongoImport() - imp.InputOptions.Type = "invalid" - So(imp.validateSettings(), ShouldNotBeNil) - }) - - Convey("an error should be thrown if neither --headerline is supplied "+ - "nor --fields/--fieldFile", func() { - imp := NewMockMongoImport() - imp.InputOptions.Type = CSV - So(imp.validateSettings(), ShouldNotBeNil) - }) - - Convey("no error should be thrown if --headerline is not supplied "+ - "but --fields is supplied", func() { - imp := NewMockMongoImport() - fields := "a,b,c" - imp.InputOptions.Fields = &fields - imp.InputOptions.Type = CSV - So(imp.validateSettings(), ShouldBeNil) - }) - - Convey("no error should be thrown if no input type is supplied", func() { - imp := NewMockMongoImport() - So(imp.validateSettings(), ShouldBeNil) - }) - - Convey("no error should be thrown if there's just one positional argument", func() { - imp := NewMockMongoImport() - So(imp.validateSettings(), ShouldBeNil) - }) - - Convey("no error should be thrown if --file is used with one positional argument", func() { - imp := NewMockMongoImport() - imp.InputOptions.File = "abc" - So(imp.validateSettings(), ShouldBeNil) - }) - - Convey("no error should be thrown if there's more than one positional argument", func() { - imp := NewMockMongoImport() - So(imp.validateSettings(), ShouldBeNil) - }) - - Convey("an error should be thrown if --headerline is used with JSON input", func() { - imp := NewMockMongoImport() - imp.InputOptions.HeaderLine = true - So(imp.validateSettings(), ShouldNotBeNil) - }) - - Convey("an error should be thrown if --fields is used with JSON input", func() { - imp := NewMockMongoImport() - fields := "" - imp.InputOptions.Fields = &fields - So(imp.validateSettings(), ShouldNotBeNil) - fields = "a,b,c" - imp.InputOptions.Fields = &fields - So(imp.validateSettings(), ShouldNotBeNil) - }) - - Convey("an error should be thrown if --fieldFile is used with JSON input", func() { - imp := NewMockMongoImport() - fieldFile := "" - imp.InputOptions.FieldFile = &fieldFile - So(imp.validateSettings(), ShouldNotBeNil) - fieldFile = "test.csv" - imp.InputOptions.FieldFile = &fieldFile - So(imp.validateSettings(), ShouldNotBeNil) - }) - - Convey("an error should be thrown if --ignoreBlanks is used with JSON input", func() { - imp := NewMockMongoImport() - imp.IngestOptions.IgnoreBlanks = true - So(imp.validateSettings(), ShouldNotBeNil) - }) - - Convey("no error should be thrown if --headerline is not supplied "+ - "but --fieldFile is supplied", func() { - imp := NewMockMongoImport() - fieldFile := "test.csv" - imp.InputOptions.FieldFile = &fieldFile - imp.InputOptions.Type = CSV - So(imp.validateSettings(), ShouldBeNil) - }) - - Convey("an error should be thrown if --mode is incorrect", func() { - imp := NewMockMongoImport() - imp.IngestOptions.Mode = "wrong" - So(imp.validateSettings(), ShouldNotBeNil) - }) - - Convey("an error should be thrown if a field in the --upsertFields "+ - "argument starts with a dollar sign", func() { - imp := NewMockMongoImport() - imp.InputOptions.HeaderLine = true - imp.InputOptions.Type = CSV - imp.IngestOptions.Mode = modeUpsert - imp.IngestOptions.UpsertFields = "a,$b,c" - So(imp.validateSettings(), ShouldNotBeNil) - imp.IngestOptions.UpsertFields = "a,.b,c" - So(imp.validateSettings(), ShouldNotBeNil) - }) - - Convey("no error should be thrown if --upsertFields is supplied without "+ - "--mode=xxx", func() { - imp := NewMockMongoImport() - imp.InputOptions.HeaderLine = true - imp.InputOptions.Type = CSV - imp.IngestOptions.UpsertFields = "a,b,c" - So(imp.validateSettings(), ShouldBeNil) - So(imp.IngestOptions.Mode, ShouldEqual, modeUpsert) - }) - - Convey("an error should be thrown if --upsertFields is used with "+ - "--mode=insert", func() { - imp := NewMockMongoImport() - imp.InputOptions.HeaderLine = true - imp.InputOptions.Type = CSV - imp.IngestOptions.Mode = modeInsert - imp.IngestOptions.UpsertFields = "a" - So(imp.validateSettings(), ShouldNotBeNil) - }) - - Convey("if --mode=upsert is used without --upsertFields, _id should be set as "+ - "the upsert field", func() { - imp := NewMockMongoImport() - imp.InputOptions.HeaderLine = true - imp.InputOptions.Type = CSV - imp.IngestOptions.Mode = modeUpsert - imp.IngestOptions.UpsertFields = "" - So(imp.validateSettings(), ShouldBeNil) - So(imp.upsertFields, ShouldResemble, []string{"_id"}) - }) - - Convey("if --mode=delete is used without --upsertFields, _id should be set as "+ - "the upsert field", func() { - imp := NewMockMongoImport() - imp.InputOptions.HeaderLine = true - imp.InputOptions.Type = CSV - imp.IngestOptions.Mode = modeDelete - imp.IngestOptions.UpsertFields = "" - So(imp.validateSettings(), ShouldBeNil) - So(imp.upsertFields, ShouldResemble, []string{"_id"}) - }) - - Convey("no error should be thrown if all fields in the --upsertFields "+ - "argument are valid", func() { - imp := NewMockMongoImport() - imp.InputOptions.HeaderLine = true - imp.InputOptions.Type = CSV - imp.IngestOptions.Mode = modeUpsert - imp.IngestOptions.UpsertFields = "a,b,c" - So(imp.validateSettings(), ShouldBeNil) - }) - - Convey("no error should be thrown if --fields is supplied with CSV import", func() { - imp := NewMockMongoImport() - fields := "a,b,c" - imp.InputOptions.Fields = &fields - imp.InputOptions.Type = CSV - So(imp.validateSettings(), ShouldBeNil) - }) - - Convey( - "an error should be thrown if an empty --fields is supplied with CSV import", - func() { - imp := NewMockMongoImport() + // check covers the handful of cases that also assert a side effect of + // validation, such as the derived collection name or upsert fields. + cases := []struct { + name string + setup func(imp *MongoImport) + wantErr bool + check func(t *testing.T, imp *MongoImport) + }{ + { + name: "an error should be thrown if no collection is given", + setup: func(imp *MongoImport) { + imp.ToolOptions.DB = "" + imp.ToolOptions.Collection = "" + }, + wantErr: true, + }, + { + name: "an error should be thrown if an invalid type is given", + setup: func(imp *MongoImport) { + imp.InputOptions.Type = "invalid" + }, + wantErr: true, + }, + { + name: "an error should be thrown if neither --headerline is supplied " + + "nor --fields/--fieldFile", + setup: func(imp *MongoImport) { + imp.InputOptions.Type = CSV + }, + wantErr: true, + }, + { + name: "no error should be thrown if --headerline is not supplied " + + "but --fields is supplied", + setup: func(imp *MongoImport) { + fields := "a,b,c" + imp.InputOptions.Fields = &fields + imp.InputOptions.Type = CSV + }, + }, + { + name: "no error should be thrown if no input type is supplied", + setup: func(imp *MongoImport) {}, + }, + { + name: "no error should be thrown if there's just one positional argument", + setup: func(imp *MongoImport) {}, + }, + { + name: "no error should be thrown if --file is used with one positional argument", + setup: func(imp *MongoImport) { + imp.InputOptions.File = "abc" + }, + }, + { + name: "no error should be thrown if there's more than one positional argument", + setup: func(imp *MongoImport) {}, + }, + { + name: "an error should be thrown if --headerline is used with JSON input", + setup: func(imp *MongoImport) { + imp.InputOptions.HeaderLine = true + }, + wantErr: true, + }, + { + name: "an error should be thrown if an empty --fields is used with JSON input", + setup: func(imp *MongoImport) { fields := "" imp.InputOptions.Fields = &fields + }, + wantErr: true, + }, + { + name: "an error should be thrown if a non-empty --fields is used with JSON input", + setup: func(imp *MongoImport) { + fields := "a,b,c" + imp.InputOptions.Fields = &fields + }, + wantErr: true, + }, + { + name: "an error should be thrown if an empty --fieldFile is used with JSON input", + setup: func(imp *MongoImport) { + fieldFile := "" + imp.InputOptions.FieldFile = &fieldFile + }, + wantErr: true, + }, + { + name: "an error should be thrown if a non-empty --fieldFile is used with JSON input", + setup: func(imp *MongoImport) { + fieldFile := "test.csv" + imp.InputOptions.FieldFile = &fieldFile + }, + wantErr: true, + }, + { + name: "an error should be thrown if --ignoreBlanks is used with JSON input", + setup: func(imp *MongoImport) { + imp.IngestOptions.IgnoreBlanks = true + }, + wantErr: true, + }, + { + name: "no error should be thrown if --headerline is not supplied " + + "but --fieldFile is supplied", + setup: func(imp *MongoImport) { + fieldFile := "test.csv" + imp.InputOptions.FieldFile = &fieldFile imp.InputOptions.Type = CSV - So(imp.validateSettings(), ShouldBeNil) }, - ) - - Convey("no error should be thrown if --fieldFile is supplied with CSV import", func() { - imp := NewMockMongoImport() - fieldFile := "test.csv" - imp.InputOptions.FieldFile = &fieldFile - imp.InputOptions.Type = CSV - So(imp.validateSettings(), ShouldBeNil) - }) + }, + { + name: "an error should be thrown if --mode is incorrect", + setup: func(imp *MongoImport) { + imp.IngestOptions.Mode = "wrong" + }, + wantErr: true, + }, + { + name: "an error should be thrown if a field in the --upsertFields " + + "argument starts with a dollar sign", + setup: func(imp *MongoImport) { + imp.InputOptions.HeaderLine = true + imp.InputOptions.Type = CSV + imp.IngestOptions.Mode = modeUpsert + imp.IngestOptions.UpsertFields = "a,$b,c" + }, + wantErr: true, + }, + { + name: "an error should be thrown if a field in the --upsertFields " + + "argument starts with a dot", + setup: func(imp *MongoImport) { + imp.InputOptions.HeaderLine = true + imp.InputOptions.Type = CSV + imp.IngestOptions.Mode = modeUpsert + imp.IngestOptions.UpsertFields = "a,.b,c" + }, + wantErr: true, + }, + { + name: "no error should be thrown if --upsertFields is supplied without " + + "--mode=xxx", + setup: func(imp *MongoImport) { + imp.InputOptions.HeaderLine = true + imp.InputOptions.Type = CSV + imp.IngestOptions.UpsertFields = "a,b,c" + }, + check: func(t *testing.T, imp *MongoImport) { + t.Helper() + assert.Equal(t, modeUpsert, imp.IngestOptions.Mode, + "should default --mode to upsert") + }, + }, + { + name: "an error should be thrown if --upsertFields is used with " + + "--mode=insert", + setup: func(imp *MongoImport) { + imp.InputOptions.HeaderLine = true + imp.InputOptions.Type = CSV + imp.IngestOptions.Mode = modeInsert + imp.IngestOptions.UpsertFields = "a" + }, + wantErr: true, + }, + { + name: "if --mode=upsert is used without --upsertFields, _id should be set as " + + "the upsert field", + setup: func(imp *MongoImport) { + imp.InputOptions.HeaderLine = true + imp.InputOptions.Type = CSV + imp.IngestOptions.Mode = modeUpsert + imp.IngestOptions.UpsertFields = "" + }, + check: func(t *testing.T, imp *MongoImport) { + t.Helper() + assert.Equal(t, []string{"_id"}, imp.upsertFields, "should default to _id") + }, + }, + { + name: "if --mode=delete is used without --upsertFields, _id should be set as " + + "the upsert field", + setup: func(imp *MongoImport) { + imp.InputOptions.HeaderLine = true + imp.InputOptions.Type = CSV + imp.IngestOptions.Mode = modeDelete + imp.IngestOptions.UpsertFields = "" + }, + check: func(t *testing.T, imp *MongoImport) { + t.Helper() + assert.Equal(t, []string{"_id"}, imp.upsertFields, "should default to _id") + }, + }, + { + name: "no error should be thrown if all fields in the --upsertFields " + + "argument are valid", + setup: func(imp *MongoImport) { + imp.InputOptions.HeaderLine = true + imp.InputOptions.Type = CSV + imp.IngestOptions.Mode = modeUpsert + imp.IngestOptions.UpsertFields = "a,b,c" + }, + }, + { + name: "no error should be thrown if --fields is supplied with CSV import", + setup: func(imp *MongoImport) { + fields := "a,b,c" + imp.InputOptions.Fields = &fields + imp.InputOptions.Type = CSV + }, + }, + { + // The original test's name claims an error should be thrown, but + // it asserts ShouldBeNil; preserved verbatim, see "Weak tests + // noticed" in the PR description. + name: "an error should be thrown if an empty --fields is supplied with CSV import", + setup: func(imp *MongoImport) { + fields := "" + imp.InputOptions.Fields = &fields + imp.InputOptions.Type = CSV + }, + }, + { + name: "no error should be thrown if --fieldFile is supplied with CSV import", + setup: func(imp *MongoImport) { + fieldFile := "test.csv" + imp.InputOptions.FieldFile = &fieldFile + imp.InputOptions.Type = CSV + }, + }, + { + name: "an error should be thrown if no collection and no file is supplied", + setup: func(imp *MongoImport) { + fieldFile := "test.csv" + imp.InputOptions.FieldFile = &fieldFile + imp.InputOptions.Type = CSV + imp.ToolOptions.Collection = "" + }, + wantErr: true, + }, + { + name: "no error should be thrown if --file is used (without -c) supplied " + + "- the file name should be used as the collection name", + setup: func(imp *MongoImport) { + imp.InputOptions.File = "input" + imp.InputOptions.HeaderLine = true + imp.InputOptions.Type = CSV + imp.ToolOptions.Collection = "" + }, + check: func(t *testing.T, imp *MongoImport) { + t.Helper() + assert.Equal(t, imp.InputOptions.File, imp.ToolOptions.Collection, + "should derive the collection name from the file name") + }, + }, + { + name: "with no collection name and a file name the base name of the " + + "file (without the extension) should be used as the collection name", + setup: func(imp *MongoImport) { + imp.InputOptions.File = "/path/to/input/file/dot/input.txt" + imp.InputOptions.HeaderLine = true + imp.InputOptions.Type = CSV + imp.ToolOptions.Collection = "" + }, + check: func(t *testing.T, imp *MongoImport) { + t.Helper() + assert.Equal(t, "input", imp.ToolOptions.Collection, + "should derive the collection name from the file's base name") + }, + }, + { + name: "an error should be thrown with a system. collection", + setup: func(imp *MongoImport) { + imp.InputOptions.File = "input" + imp.InputOptions.HeaderLine = true + imp.InputOptions.Type = CSV + imp.ToolOptions.Collection = common.TimeseriesBucketPrefix + "foo" + }, + wantErr: true, + }, + { + name: "error should be thrown if --legacy is specified and input type is not JSON", + setup: func(imp *MongoImport) { + imp.InputOptions.Type = CSV + fieldFile := "test.csv" + imp.InputOptions.FieldFile = &fieldFile + imp.InputOptions.Legacy = true + }, + wantErr: true, + }, + } - Convey("an error should be thrown if no collection and no file is supplied", func() { - imp := NewMockMongoImport() - fieldFile := "test.csv" - imp.InputOptions.FieldFile = &fieldFile - imp.InputOptions.Type = CSV - imp.ToolOptions.Collection = "" - So(imp.validateSettings(), ShouldNotBeNil) - }) + for _, tc := range cases { + imp := NewMockMongoImport() + tc.setup(imp) + err := imp.validateSettings() + if tc.wantErr { + assert.Error(t, err, tc.name) + } else { + assert.NoError(t, err, tc.name) + } + if tc.check != nil { + tc.check(t, imp) + } + } +} - Convey("no error should be thrown if --file is used (without -c) supplied "+ - "- the file name should be used as the collection name", func() { - imp := NewMockMongoImport() - imp.InputOptions.File = "input" - imp.InputOptions.HeaderLine = true - imp.InputOptions.Type = CSV - imp.ToolOptions.Collection = "" - So(imp.validateSettings(), ShouldBeNil) - So(imp.ToolOptions.Collection, ShouldEqual, - imp.InputOptions.File) - }) +func TestGetSourceReader(t *testing.T) { + testtype.SkipUnlessTestType(t, testtype.UnitTestType) - Convey("with no collection name and a file name the base name of the "+ - "file (without the extension) should be used as the collection name", func() { + t.Run("an error should be thrown if the given file referenced by the reader does not exist", + func(t *testing.T) { imp := NewMockMongoImport() imp.InputOptions.File = "/path/to/input/file/dot/input.txt" - imp.InputOptions.HeaderLine = true imp.InputOptions.Type = CSV imp.ToolOptions.Collection = "" - So(imp.validateSettings(), ShouldBeNil) - So(imp.ToolOptions.Collection, ShouldEqual, "input") + _, _, err := imp.getSourceReader() + assert.Error(t, err, "should reject a nonexistent input file") }) - Convey("an error should be thrown with a system. collection", func() { - imp := NewMockMongoImport() - imp.InputOptions.File = "input" - imp.InputOptions.HeaderLine = true - imp.InputOptions.Type = CSV - imp.ToolOptions.Collection = common.TimeseriesBucketPrefix + "foo" - So(imp.validateSettings(), ShouldNotBeNil) - }) + t.Run("no error should be thrown if the file exists", func(t *testing.T) { + imp := NewMockMongoImport() + imp.InputOptions.File = "testdata/test_array.json" + imp.InputOptions.Type = JSON + _, _, err := imp.getSourceReader() + assert.NoError(t, err, "should accept an existing input file") + }) - Convey( - "error should be thrown if --legacy is specified and input type is not JSON", - func() { - imp := NewMockMongoImport() - imp.InputOptions.Type = CSV - fieldFile := "test.csv" - imp.InputOptions.FieldFile = &fieldFile - imp.InputOptions.Legacy = true - So(imp.validateSettings(), ShouldNotBeNil) - }, - ) + t.Run("no error should be thrown if stdin is used", func(t *testing.T) { + imp := NewMockMongoImport() + imp.InputOptions.File = "" + _, _, err := imp.getSourceReader() + assert.NoError(t, err, "should accept stdin as the input source") }) } -func TestGetSourceReader(t *testing.T) { +func TestGetInputReader(t *testing.T) { testtype.SkipUnlessTestType(t, testtype.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 := NewMockMongoImport() + + cases := []struct { + name string + setup func(imp *MongoImport) + wantErr bool + }{ + { + name: "should parse --fields using valid csv escaping", + setup: func(imp *MongoImport) { + imp.InputOptions.Fields = new(string) + *imp.InputOptions.Fields = "foo.auto(),bar.date(January 2, 2006)" + imp.InputOptions.File = "/path/to/input/file/dot/input.txt" + imp.InputOptions.ColumnsHaveTypes = true + }, + }, + { + name: "should complain about non-escaped new lines in --fields", + setup: func(imp *MongoImport) { + imp.InputOptions.Fields = new(string) + *imp.InputOptions.Fields = "foo.auto(),\nblah.binary(hex),bar.date(January 2, 2006)" imp.InputOptions.File = "/path/to/input/file/dot/input.txt" + imp.InputOptions.ColumnsHaveTypes = true + }, + }, + { + name: "no error should be thrown if neither --fields nor --fieldFile " + + "is used", + setup: func(imp *MongoImport) { + imp.InputOptions.File = "/path/to/input/file/dot/input.txt" + }, + }, + { + name: "no error should be thrown if --fields is used", + setup: func(imp *MongoImport) { + fields := "a,b,c" + imp.InputOptions.Fields = &fields + imp.InputOptions.File = "/path/to/input/file/dot/input.txt" + }, + }, + { + name: "no error should be thrown if --fieldFile is used and it " + + "references a valid file", + setup: func(imp *MongoImport) { + fieldFile := "testdata/test.csv" + imp.InputOptions.FieldFile = &fieldFile + }, + }, + { + name: "an error should be thrown if --fieldFile is used and it " + + "references an invalid file", + setup: func(imp *MongoImport) { + fieldFile := "/path/to/input/file/dot/input.txt" + imp.InputOptions.FieldFile = &fieldFile + }, + wantErr: true, + }, + { + name: "no error should be thrown for CSV import inputs", + setup: func(imp *MongoImport) { imp.InputOptions.Type = CSV - imp.ToolOptions.Collection = "" - _, _, err := imp.getSourceReader() - So(err, ShouldNotBeNil) - }) - - Convey("no error should be thrown if the file exists", func() { - imp := NewMockMongoImport() - imp.InputOptions.File = "testdata/test_array.json" + }, + }, + { + name: "no error should be thrown for TSV import inputs", + setup: func(imp *MongoImport) { + imp.InputOptions.Type = TSV + }, + }, + { + name: "no error should be thrown for JSON import inputs", + setup: func(imp *MongoImport) { imp.InputOptions.Type = JSON - _, _, err := imp.getSourceReader() - So(err, ShouldBeNil) - }) + }, + }, + } - Convey("no error should be thrown if stdin is used", func() { - imp := NewMockMongoImport() - imp.InputOptions.File = "" - _, _, err := imp.getSourceReader() - So(err, ShouldBeNil) - }) - }) -} + for _, tc := range cases { + imp := NewMockMongoImport() + tc.setup(imp) + _, err := imp.getInputReader(&os.File{}) + if tc.wantErr { + assert.Error(t, err, tc.name) + } else { + assert.NoError(t, err, tc.name) + } + } -func TestGetInputReader(t *testing.T) { - testtype.SkipUnlessTestType(t, testtype.UnitTestType) - Convey("Given a io.Reader on calling getInputReader", t, func() { - Convey("should parse --fields using valid csv escaping", func() { - imp := NewMockMongoImport() - imp.InputOptions.Fields = new(string) - *imp.InputOptions.Fields = "foo.auto(),bar.date(January 2, 2006)" - imp.InputOptions.File = "/path/to/input/file/dot/input.txt" - imp.InputOptions.ColumnsHaveTypes = true - _, err := imp.getInputReader(&os.File{}) - So(err, ShouldBeNil) - }) - Convey("should complain about non-escaped new lines in --fields", func() { - imp := NewMockMongoImport() - imp.InputOptions.Fields = new(string) - *imp.InputOptions.Fields = "foo.auto(),\nblah.binary(hex),bar.date(January 2, 2006)" - imp.InputOptions.File = "/path/to/input/file/dot/input.txt" - imp.InputOptions.ColumnsHaveTypes = true - _, err := imp.getInputReader(&os.File{}) - So(err, ShouldBeNil) - }) - Convey("no error should be thrown if neither --fields nor --fieldFile "+ - "is used", func() { - imp := NewMockMongoImport() - imp.InputOptions.File = "/path/to/input/file/dot/input.txt" - _, err := imp.getInputReader(&os.File{}) - So(err, ShouldBeNil) - }) - Convey("no error should be thrown if --fields is used", func() { - imp := NewMockMongoImport() - fields := "a,b,c" - imp.InputOptions.Fields = &fields - imp.InputOptions.File = "/path/to/input/file/dot/input.txt" - _, err := imp.getInputReader(&os.File{}) - So(err, ShouldBeNil) - }) - Convey("no error should be thrown if --fieldFile is used and it "+ - "references a valid file", func() { - imp := NewMockMongoImport() - fieldFile := "testdata/test.csv" - imp.InputOptions.FieldFile = &fieldFile - _, err := imp.getInputReader(&os.File{}) - So(err, ShouldBeNil) - }) - Convey("an error should be thrown if --fieldFile is used and it "+ - "references an invalid file", func() { - imp := NewMockMongoImport() - fieldFile := "/path/to/input/file/dot/input.txt" - imp.InputOptions.FieldFile = &fieldFile - _, err := imp.getInputReader(&os.File{}) - So(err, ShouldNotBeNil) - }) - Convey("no error should be thrown for CSV import inputs", func() { - imp := NewMockMongoImport() - imp.InputOptions.Type = CSV - _, err := imp.getInputReader(&os.File{}) - So(err, ShouldBeNil) - }) - Convey("no error should be thrown for TSV import inputs", func() { - imp := NewMockMongoImport() - imp.InputOptions.Type = TSV - _, err := imp.getInputReader(&os.File{}) - So(err, ShouldBeNil) - }) - Convey("no error should be thrown for JSON import inputs", func() { - imp := NewMockMongoImport() - imp.InputOptions.Type = JSON - _, err := imp.getInputReader(&os.File{}) - So(err, ShouldBeNil) - }) - Convey("an error should be thrown if --fieldFile fields are invalid", func() { - imp := NewMockMongoImport() - fieldFile := "testdata/test_fields_invalid.txt" - imp.InputOptions.FieldFile = &fieldFile - file, err := os.Open(fieldFile) - So(err, ShouldBeNil) - _, err = imp.getInputReader(file) - So(err, ShouldNotBeNil) - }) - Convey("no error should be thrown if --fieldFile fields are valid", func() { - imp := NewMockMongoImport() - fieldFile := "testdata/test_fields_valid.txt" - imp.InputOptions.FieldFile = &fieldFile - file, err := os.Open(fieldFile) - So(err, ShouldBeNil) - _, err = imp.getInputReader(file) - So(err, ShouldBeNil) - }) + t.Run("an error should be thrown if --fieldFile fields are invalid", func(t *testing.T) { + imp := NewMockMongoImport() + fieldFile := "testdata/test_fields_invalid.txt" + imp.InputOptions.FieldFile = &fieldFile + file, err := os.Open(fieldFile) + require.NoError(t, err, "should open the fixture file") + _, err = imp.getInputReader(file) + assert.Error(t, err, "should reject invalid --fieldFile fields") + }) + + t.Run("no error should be thrown if --fieldFile fields are valid", func(t *testing.T) { + imp := NewMockMongoImport() + fieldFile := "testdata/test_fields_valid.txt" + imp.InputOptions.FieldFile = &fieldFile + file, err := os.Open(fieldFile) + require.NoError(t, err, "should open the fixture file") + _, err = imp.getInputReader(file) + assert.NoError(t, err, "should accept valid --fieldFile fields") }) }