-
-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Json generator
- Loading branch information
Showing
3 changed files
with
163 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package faker | ||
|
||
import ( | ||
"encoding/json" | ||
"strconv" | ||
) | ||
|
||
// Json is a faker struct for json files | ||
type Json struct { | ||
Faker *Faker | ||
} | ||
|
||
var ( | ||
attributesTypes = []string{"string", "number", "object", "array", "boolean", "null"} | ||
attributesTypesWithoutArrayAndObject = []string{"string", "number", "boolean", "null"} | ||
) | ||
|
||
func (j *Json) randomAttributeValueFromListAsString(validAttributesTypes []string) string { | ||
attributeType := j.Faker.RandomStringElement(validAttributesTypes) | ||
switch attributeType { | ||
case "string": | ||
return "\"" + j.Faker.Lorem().Word() + "\"" | ||
case "number": | ||
number := strconv.Itoa(j.Faker.RandomNumber(j.Faker.RandomDigit())) | ||
return number | ||
case "object": | ||
// Avoid having multiple nested objects by not using object and array as valid attribute types | ||
return j.randomJsonObjectAsString(attributesTypesWithoutArrayAndObject) | ||
case "array": | ||
objects := "" | ||
for i := 0; i < j.Faker.IntBetween(1, 10); i++ { | ||
if objects != "" { | ||
objects += ", " | ||
} | ||
// Avoid having multiple nested objects by not using object and array as valid attribute types | ||
objects += j.randomJsonObjectAsString(attributesTypesWithoutArrayAndObject) | ||
} | ||
return "[" + objects + "]" | ||
case "boolean": | ||
return j.Faker.RandomStringElement([]string{"true", "false"}) | ||
case "null": | ||
return "null" | ||
} | ||
|
||
panic("Invalid attribute type: " + attributeType) | ||
} | ||
|
||
func (j *Json) randomJsonObjectAsString(validAttributesTypes []string) string { | ||
numberAttributes := j.Faker.IntBetween(1, 10) | ||
attributes := make([]string, numberAttributes) | ||
for i := 0; i < numberAttributes; i++ { | ||
attributeName := j.Faker.Lorem().Word() | ||
attributeValue := j.randomAttributeValueFromListAsString(validAttributesTypes) | ||
attributes[i] = "\"" + attributeName + "\": " + attributeValue | ||
} | ||
|
||
result := "{" | ||
for i := 0; i < len(attributes); i++ { | ||
if i > 0 { | ||
result += ", " | ||
} | ||
result += attributes[i] | ||
} | ||
result += "}" | ||
return result | ||
} | ||
|
||
// String generates a random json string | ||
func (j *Json) String() string { | ||
return j.randomJsonObjectAsString(attributesTypes) | ||
} | ||
|
||
// Object generates a random json object | ||
func (j *Json) Object() map[string]interface{} { | ||
result := j.String() | ||
var data map[string]interface{} | ||
json.Unmarshal([]byte(result), &data) | ||
return data | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package faker | ||
|
||
import ( | ||
"encoding/json" | ||
"testing" | ||
) | ||
|
||
func TestJsonString(t *testing.T) { | ||
faker := New() | ||
j := faker.Json() | ||
|
||
for i := 0; i < 10; i++ { | ||
result := j.String() | ||
|
||
// Attempt to unmarshal the result into a map[string]interface{} | ||
var data map[string]interface{} | ||
err := json.Unmarshal([]byte(result), &data) | ||
Expect(t, err, nil) | ||
|
||
// Ensure that the result is a valid JSON object | ||
Expect(t, len(data) > 0, true) | ||
|
||
// Ensure that all attribute values are valid JSON types | ||
for _, value := range data { | ||
switch value.(type) { | ||
case string, float64, bool, nil: | ||
// Valid JSON types | ||
case []interface{}: | ||
// Valid JSON array type | ||
case map[string]interface{}: | ||
// Valid JSON object type | ||
default: | ||
t.FailNow() | ||
} | ||
} | ||
} | ||
} | ||
|
||
func TestJsonObject(t *testing.T) { | ||
faker := New() | ||
j := faker.Json() | ||
|
||
for i := 0; i < 10; i++ { | ||
data := j.Object() | ||
|
||
// Ensure that the result is not nil | ||
NotExpect(t, data, nil) | ||
|
||
// Ensure that the result is a valid JSON object | ||
Expect(t, len(data) > 0, true) | ||
|
||
// Ensure that all attribute values are valid JSON types | ||
for _, value := range data { | ||
switch value.(type) { | ||
case string, float64, bool, nil: | ||
// Valid JSON types | ||
case []interface{}: | ||
// Valid JSON array type | ||
case map[string]interface{}: | ||
// Valid JSON object type | ||
default: | ||
t.FailNow() | ||
} | ||
} | ||
} | ||
} | ||
|
||
func TestRandomAttributeValueFromListAsStringPanicWhenUnsupportedTypeIsPassed(t *testing.T) { | ||
faker := New() | ||
j := faker.Json() | ||
|
||
defer func() { | ||
if r := recover(); r == nil { | ||
NotExpect(t, r, nil) | ||
} | ||
}() | ||
|
||
j.randomAttributeValueFromListAsString([]string{"unsupported"}) | ||
} |