Add randomize support for enums, add enums for pq

This commit is contained in:
Patrick O'brien 2016-11-12 15:47:24 +10:00
parent 6f0fce21b8
commit d891bcb9f0
4 changed files with 102 additions and 0 deletions

View file

@ -1047,6 +1047,43 @@ exists, err := jet.Pilot(db).Exists()
exists, err := models.Pilots(db, Where("id=?", 5)).Exists()
```
### Enums
If your MySQL or Postgres tables use enums we will generate constants that hold their values
that you can use in your queries. For example:
```
CREATE TYPE workday AS ENUM('monday', 'tuesday', 'wednesday', 'thursday', 'friday');
CREATE TABLE event_one (
id serial PRIMARY KEY NOT NULL,
name VARCHAR(255),
day workday NOT NULL
);
```
An enum type defined like the above, being used by a table, will generate the following enums:
```
const (
WorkdayMonday = "monday"
WorkdayTuesday = "tuesday"
WorkdayWednesday = "wednesday"
WorkdayThursday = "thursday"
WorkdayFriday = "friday"
)
```
For Postgres we use `enum type name + title cased` value to generate the const variable name.
For MySQL we use `table name + column name + title cased value` to generate the const variable name.
Note: If your enum holds a value we cannot parse correctly due, to non-alphabet characters for example,
it may not be generated. In this event, you will receive errors in your generated tests because
the value randomizer in the test suite does not know how to generate valid enum values. You will
still be able to use your generated library, and it will still work as expected, but the only way
to get the tests to pass in this event is to either use a parsable enum value or use a regular column
instead of an enum.
## FAQ
#### Won't compiling models for a huge database be very slow?

View file

@ -158,6 +158,16 @@ func randDate(s *Seed) time.Time {
// If canBeNull is true:
// The value has the possibility of being null or non-zero at random.
func randomizeField(s *Seed, field reflect.Value, fieldType string, canBeNull bool) error {
if strings.HasPrefix(fieldType, "enum") {
enum, err := randEnumValue(fieldType)
if err != nil {
return err
}
field.Set(reflect.ValueOf(enum))
return nil
}
kind := field.Kind()
typ := field.Type()
@ -604,3 +614,12 @@ func getVariableRandValue(s *Seed, kind reflect.Kind, typ reflect.Type) interfac
return nil
}
func randEnumValue(enum string) (string, error) {
vals := strmangle.ParseEnumVals(enum)
if vals == nil || len(vals) == 0 {
return "", fmt.Errorf("unable to parse enum string: %s", enum)
}
return vals[rand.Intn(len(vals)-1)], nil
}

View file

@ -144,3 +144,28 @@ func TestRandomizeField(t *testing.T) {
}
}
}
func TestRandEnumValue(t *testing.T) {
t.Parallel()
enum1 := "enum.workday('monday','tuesday')"
enum2 := "enum('monday','tuesday')"
r1, err := randEnumValue(enum1)
if err != nil {
t.Error(err)
}
if r1 != "monday" && r1 != "tuesday" {
t.Errorf("Expected monday or tueday, got: %q", r1)
}
r2, err := randEnumValue(enum2)
if err != nil {
t.Error(err)
}
if r2 != "monday" && r2 != "tuesday" {
t.Errorf("Expected monday or tueday, got: %q", r2)
}
}

View file

@ -1,3 +1,24 @@
CREATE TYPE workday AS ENUM('monday', 'tuesday', 'wednesday', 'thursday', 'friday');
CREATE TYPE faceyface AS ENUM('angry', 'hungry', 'bitter');
CREATE TABLE event_one (
id serial PRIMARY KEY NOT NULL,
name VARCHAR(255),
day workday NOT NULL
);
CREATE TABLE event_two (
id serial PRIMARY KEY NOT NULL,
name VARCHAR(255),
day workday NOT NULL
);
CREATE TABLE facey (
id serial PRIMARY KEY NOT NULL,
name VARCHAR(255),
face faceyface NOT NULL
);
CREATE TABLE magic (
id serial PRIMARY KEY NOT NULL,
id_two serial NOT NULL,