// Code generated by azure-service-operator-codegen. DO NOT EDIT.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
package arm

import (
	"encoding/json"
	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
	"github.com/kr/pretty"
	"github.com/kylelemons/godebug/diff"
	"github.com/leanovate/gopter"
	"github.com/leanovate/gopter/gen"
	"github.com/leanovate/gopter/prop"
	"os"
	"reflect"
	"testing"
)

func Test_AbsoluteMonthlySchedule_WhenSerializedToJson_DeserializesAsEqual(t *testing.T) {
	t.Parallel()
	parameters := gopter.DefaultTestParameters()
	parameters.MinSuccessfulTests = 100
	parameters.MaxSize = 3
	properties := gopter.NewProperties(parameters)
	properties.Property(
		"Round trip of AbsoluteMonthlySchedule via JSON returns original",
		prop.ForAll(RunJSONSerializationTestForAbsoluteMonthlySchedule, AbsoluteMonthlyScheduleGenerator()))
	properties.TestingRun(t, gopter.NewFormatedReporter(true, 240, os.Stdout))
}

// RunJSONSerializationTestForAbsoluteMonthlySchedule runs a test to see if a specific instance of AbsoluteMonthlySchedule round trips to JSON and back losslessly
func RunJSONSerializationTestForAbsoluteMonthlySchedule(subject AbsoluteMonthlySchedule) string {
	// Serialize to JSON
	bin, err := json.Marshal(subject)
	if err != nil {
		return err.Error()
	}

	// Deserialize back into memory
	var actual AbsoluteMonthlySchedule
	err = json.Unmarshal(bin, &actual)
	if err != nil {
		return err.Error()
	}

	// Check for outcome
	match := cmp.Equal(subject, actual, cmpopts.EquateEmpty())
	if !match {
		actualFmt := pretty.Sprint(actual)
		subjectFmt := pretty.Sprint(subject)
		result := diff.Diff(subjectFmt, actualFmt)
		return result
	}

	return ""
}

// Generator of AbsoluteMonthlySchedule instances for property testing - lazily instantiated by
// AbsoluteMonthlyScheduleGenerator()
var absoluteMonthlyScheduleGenerator gopter.Gen

// AbsoluteMonthlyScheduleGenerator returns a generator of AbsoluteMonthlySchedule instances for property testing.
func AbsoluteMonthlyScheduleGenerator() gopter.Gen {
	if absoluteMonthlyScheduleGenerator != nil {
		return absoluteMonthlyScheduleGenerator
	}

	generators := make(map[string]gopter.Gen)
	AddIndependentPropertyGeneratorsForAbsoluteMonthlySchedule(generators)
	absoluteMonthlyScheduleGenerator = gen.Struct(reflect.TypeOf(AbsoluteMonthlySchedule{}), generators)

	return absoluteMonthlyScheduleGenerator
}

// AddIndependentPropertyGeneratorsForAbsoluteMonthlySchedule is a factory method for creating gopter generators
func AddIndependentPropertyGeneratorsForAbsoluteMonthlySchedule(gens map[string]gopter.Gen) {
	gens["DayOfMonth"] = gen.PtrOf(gen.Int())
	gens["IntervalMonths"] = gen.PtrOf(gen.Int())
}

func Test_DailySchedule_WhenSerializedToJson_DeserializesAsEqual(t *testing.T) {
	t.Parallel()
	parameters := gopter.DefaultTestParameters()
	parameters.MinSuccessfulTests = 100
	parameters.MaxSize = 3
	properties := gopter.NewProperties(parameters)
	properties.Property(
		"Round trip of DailySchedule via JSON returns original",
		prop.ForAll(RunJSONSerializationTestForDailySchedule, DailyScheduleGenerator()))
	properties.TestingRun(t, gopter.NewFormatedReporter(true, 240, os.Stdout))
}

// RunJSONSerializationTestForDailySchedule runs a test to see if a specific instance of DailySchedule round trips to JSON and back losslessly
func RunJSONSerializationTestForDailySchedule(subject DailySchedule) string {
	// Serialize to JSON
	bin, err := json.Marshal(subject)
	if err != nil {
		return err.Error()
	}

	// Deserialize back into memory
	var actual DailySchedule
	err = json.Unmarshal(bin, &actual)
	if err != nil {
		return err.Error()
	}

	// Check for outcome
	match := cmp.Equal(subject, actual, cmpopts.EquateEmpty())
	if !match {
		actualFmt := pretty.Sprint(actual)
		subjectFmt := pretty.Sprint(subject)
		result := diff.Diff(subjectFmt, actualFmt)
		return result
	}

	return ""
}

// Generator of DailySchedule instances for property testing - lazily instantiated by DailyScheduleGenerator()
var dailyScheduleGenerator gopter.Gen

// DailyScheduleGenerator returns a generator of DailySchedule instances for property testing.
func DailyScheduleGenerator() gopter.Gen {
	if dailyScheduleGenerator != nil {
		return dailyScheduleGenerator
	}

	generators := make(map[string]gopter.Gen)
	AddIndependentPropertyGeneratorsForDailySchedule(generators)
	dailyScheduleGenerator = gen.Struct(reflect.TypeOf(DailySchedule{}), generators)

	return dailyScheduleGenerator
}

// AddIndependentPropertyGeneratorsForDailySchedule is a factory method for creating gopter generators
func AddIndependentPropertyGeneratorsForDailySchedule(gens map[string]gopter.Gen) {
	gens["IntervalDays"] = gen.PtrOf(gen.Int())
}

func Test_DateSpan_WhenSerializedToJson_DeserializesAsEqual(t *testing.T) {
	t.Parallel()
	parameters := gopter.DefaultTestParameters()
	parameters.MinSuccessfulTests = 100
	parameters.MaxSize = 3
	properties := gopter.NewProperties(parameters)
	properties.Property(
		"Round trip of DateSpan via JSON returns original",
		prop.ForAll(RunJSONSerializationTestForDateSpan, DateSpanGenerator()))
	properties.TestingRun(t, gopter.NewFormatedReporter(true, 240, os.Stdout))
}

// RunJSONSerializationTestForDateSpan runs a test to see if a specific instance of DateSpan round trips to JSON and back losslessly
func RunJSONSerializationTestForDateSpan(subject DateSpan) string {
	// Serialize to JSON
	bin, err := json.Marshal(subject)
	if err != nil {
		return err.Error()
	}

	// Deserialize back into memory
	var actual DateSpan
	err = json.Unmarshal(bin, &actual)
	if err != nil {
		return err.Error()
	}

	// Check for outcome
	match := cmp.Equal(subject, actual, cmpopts.EquateEmpty())
	if !match {
		actualFmt := pretty.Sprint(actual)
		subjectFmt := pretty.Sprint(subject)
		result := diff.Diff(subjectFmt, actualFmt)
		return result
	}

	return ""
}

// Generator of DateSpan instances for property testing - lazily instantiated by DateSpanGenerator()
var dateSpanGenerator gopter.Gen

// DateSpanGenerator returns a generator of DateSpan instances for property testing.
func DateSpanGenerator() gopter.Gen {
	if dateSpanGenerator != nil {
		return dateSpanGenerator
	}

	generators := make(map[string]gopter.Gen)
	AddIndependentPropertyGeneratorsForDateSpan(generators)
	dateSpanGenerator = gen.Struct(reflect.TypeOf(DateSpan{}), generators)

	return dateSpanGenerator
}

// AddIndependentPropertyGeneratorsForDateSpan is a factory method for creating gopter generators
func AddIndependentPropertyGeneratorsForDateSpan(gens map[string]gopter.Gen) {
	gens["End"] = gen.PtrOf(gen.AlphaString())
	gens["Start"] = gen.PtrOf(gen.AlphaString())
}

func Test_MaintenanceConfigurationProperties_WhenSerializedToJson_DeserializesAsEqual(t *testing.T) {
	t.Parallel()
	parameters := gopter.DefaultTestParameters()
	parameters.MinSuccessfulTests = 100
	parameters.MaxSize = 3
	properties := gopter.NewProperties(parameters)
	properties.Property(
		"Round trip of MaintenanceConfigurationProperties via JSON returns original",
		prop.ForAll(RunJSONSerializationTestForMaintenanceConfigurationProperties, MaintenanceConfigurationPropertiesGenerator()))
	properties.TestingRun(t, gopter.NewFormatedReporter(true, 240, os.Stdout))
}

// RunJSONSerializationTestForMaintenanceConfigurationProperties runs a test to see if a specific instance of MaintenanceConfigurationProperties round trips to JSON and back losslessly
func RunJSONSerializationTestForMaintenanceConfigurationProperties(subject MaintenanceConfigurationProperties) string {
	// Serialize to JSON
	bin, err := json.Marshal(subject)
	if err != nil {
		return err.Error()
	}

	// Deserialize back into memory
	var actual MaintenanceConfigurationProperties
	err = json.Unmarshal(bin, &actual)
	if err != nil {
		return err.Error()
	}

	// Check for outcome
	match := cmp.Equal(subject, actual, cmpopts.EquateEmpty())
	if !match {
		actualFmt := pretty.Sprint(actual)
		subjectFmt := pretty.Sprint(subject)
		result := diff.Diff(subjectFmt, actualFmt)
		return result
	}

	return ""
}

// Generator of MaintenanceConfigurationProperties instances for property testing - lazily instantiated by
// MaintenanceConfigurationPropertiesGenerator()
var maintenanceConfigurationPropertiesGenerator gopter.Gen

// MaintenanceConfigurationPropertiesGenerator returns a generator of MaintenanceConfigurationProperties instances for property testing.
func MaintenanceConfigurationPropertiesGenerator() gopter.Gen {
	if maintenanceConfigurationPropertiesGenerator != nil {
		return maintenanceConfigurationPropertiesGenerator
	}

	generators := make(map[string]gopter.Gen)
	AddRelatedPropertyGeneratorsForMaintenanceConfigurationProperties(generators)
	maintenanceConfigurationPropertiesGenerator = gen.Struct(reflect.TypeOf(MaintenanceConfigurationProperties{}), generators)

	return maintenanceConfigurationPropertiesGenerator
}

// AddRelatedPropertyGeneratorsForMaintenanceConfigurationProperties is a factory method for creating gopter generators
func AddRelatedPropertyGeneratorsForMaintenanceConfigurationProperties(gens map[string]gopter.Gen) {
	gens["MaintenanceWindow"] = gen.PtrOf(MaintenanceWindowGenerator())
	gens["NotAllowedTime"] = gen.SliceOf(TimeSpanGenerator())
	gens["TimeInWeek"] = gen.SliceOf(TimeInWeekGenerator())
}

func Test_MaintenanceConfiguration_Spec_WhenSerializedToJson_DeserializesAsEqual(t *testing.T) {
	t.Parallel()
	parameters := gopter.DefaultTestParameters()
	parameters.MinSuccessfulTests = 80
	parameters.MaxSize = 3
	properties := gopter.NewProperties(parameters)
	properties.Property(
		"Round trip of MaintenanceConfiguration_Spec via JSON returns original",
		prop.ForAll(RunJSONSerializationTestForMaintenanceConfiguration_Spec, MaintenanceConfiguration_SpecGenerator()))
	properties.TestingRun(t, gopter.NewFormatedReporter(true, 240, os.Stdout))
}

// RunJSONSerializationTestForMaintenanceConfiguration_Spec runs a test to see if a specific instance of MaintenanceConfiguration_Spec round trips to JSON and back losslessly
func RunJSONSerializationTestForMaintenanceConfiguration_Spec(subject MaintenanceConfiguration_Spec) string {
	// Serialize to JSON
	bin, err := json.Marshal(subject)
	if err != nil {
		return err.Error()
	}

	// Deserialize back into memory
	var actual MaintenanceConfiguration_Spec
	err = json.Unmarshal(bin, &actual)
	if err != nil {
		return err.Error()
	}

	// Check for outcome
	match := cmp.Equal(subject, actual, cmpopts.EquateEmpty())
	if !match {
		actualFmt := pretty.Sprint(actual)
		subjectFmt := pretty.Sprint(subject)
		result := diff.Diff(subjectFmt, actualFmt)
		return result
	}

	return ""
}

// Generator of MaintenanceConfiguration_Spec instances for property testing - lazily instantiated by
// MaintenanceConfiguration_SpecGenerator()
var maintenanceConfiguration_SpecGenerator gopter.Gen

// MaintenanceConfiguration_SpecGenerator returns a generator of MaintenanceConfiguration_Spec instances for property testing.
// We first initialize maintenanceConfiguration_SpecGenerator with a simplified generator based on the
// fields with primitive types then replacing it with a more complex one that also handles complex fields
// to ensure any cycles in the object graph properly terminate.
func MaintenanceConfiguration_SpecGenerator() gopter.Gen {
	if maintenanceConfiguration_SpecGenerator != nil {
		return maintenanceConfiguration_SpecGenerator
	}

	generators := make(map[string]gopter.Gen)
	AddIndependentPropertyGeneratorsForMaintenanceConfiguration_Spec(generators)
	maintenanceConfiguration_SpecGenerator = gen.Struct(reflect.TypeOf(MaintenanceConfiguration_Spec{}), generators)

	// The above call to gen.Struct() captures the map, so create a new one
	generators = make(map[string]gopter.Gen)
	AddIndependentPropertyGeneratorsForMaintenanceConfiguration_Spec(generators)
	AddRelatedPropertyGeneratorsForMaintenanceConfiguration_Spec(generators)
	maintenanceConfiguration_SpecGenerator = gen.Struct(reflect.TypeOf(MaintenanceConfiguration_Spec{}), generators)

	return maintenanceConfiguration_SpecGenerator
}

// AddIndependentPropertyGeneratorsForMaintenanceConfiguration_Spec is a factory method for creating gopter generators
func AddIndependentPropertyGeneratorsForMaintenanceConfiguration_Spec(gens map[string]gopter.Gen) {
	gens["Name"] = gen.AlphaString()
}

// AddRelatedPropertyGeneratorsForMaintenanceConfiguration_Spec is a factory method for creating gopter generators
func AddRelatedPropertyGeneratorsForMaintenanceConfiguration_Spec(gens map[string]gopter.Gen) {
	gens["Properties"] = gen.PtrOf(MaintenanceConfigurationPropertiesGenerator())
}

func Test_MaintenanceWindow_WhenSerializedToJson_DeserializesAsEqual(t *testing.T) {
	t.Parallel()
	parameters := gopter.DefaultTestParameters()
	parameters.MinSuccessfulTests = 100
	parameters.MaxSize = 3
	properties := gopter.NewProperties(parameters)
	properties.Property(
		"Round trip of MaintenanceWindow via JSON returns original",
		prop.ForAll(RunJSONSerializationTestForMaintenanceWindow, MaintenanceWindowGenerator()))
	properties.TestingRun(t, gopter.NewFormatedReporter(true, 240, os.Stdout))
}

// RunJSONSerializationTestForMaintenanceWindow runs a test to see if a specific instance of MaintenanceWindow round trips to JSON and back losslessly
func RunJSONSerializationTestForMaintenanceWindow(subject MaintenanceWindow) string {
	// Serialize to JSON
	bin, err := json.Marshal(subject)
	if err != nil {
		return err.Error()
	}

	// Deserialize back into memory
	var actual MaintenanceWindow
	err = json.Unmarshal(bin, &actual)
	if err != nil {
		return err.Error()
	}

	// Check for outcome
	match := cmp.Equal(subject, actual, cmpopts.EquateEmpty())
	if !match {
		actualFmt := pretty.Sprint(actual)
		subjectFmt := pretty.Sprint(subject)
		result := diff.Diff(subjectFmt, actualFmt)
		return result
	}

	return ""
}

// Generator of MaintenanceWindow instances for property testing - lazily instantiated by MaintenanceWindowGenerator()
var maintenanceWindowGenerator gopter.Gen

// MaintenanceWindowGenerator returns a generator of MaintenanceWindow instances for property testing.
// We first initialize maintenanceWindowGenerator with a simplified generator based on the
// fields with primitive types then replacing it with a more complex one that also handles complex fields
// to ensure any cycles in the object graph properly terminate.
func MaintenanceWindowGenerator() gopter.Gen {
	if maintenanceWindowGenerator != nil {
		return maintenanceWindowGenerator
	}

	generators := make(map[string]gopter.Gen)
	AddIndependentPropertyGeneratorsForMaintenanceWindow(generators)
	maintenanceWindowGenerator = gen.Struct(reflect.TypeOf(MaintenanceWindow{}), generators)

	// The above call to gen.Struct() captures the map, so create a new one
	generators = make(map[string]gopter.Gen)
	AddIndependentPropertyGeneratorsForMaintenanceWindow(generators)
	AddRelatedPropertyGeneratorsForMaintenanceWindow(generators)
	maintenanceWindowGenerator = gen.Struct(reflect.TypeOf(MaintenanceWindow{}), generators)

	return maintenanceWindowGenerator
}

// AddIndependentPropertyGeneratorsForMaintenanceWindow is a factory method for creating gopter generators
func AddIndependentPropertyGeneratorsForMaintenanceWindow(gens map[string]gopter.Gen) {
	gens["DurationHours"] = gen.PtrOf(gen.Int())
	gens["StartDate"] = gen.PtrOf(gen.AlphaString())
	gens["StartTime"] = gen.PtrOf(gen.AlphaString())
	gens["UtcOffset"] = gen.PtrOf(gen.AlphaString())
}

// AddRelatedPropertyGeneratorsForMaintenanceWindow is a factory method for creating gopter generators
func AddRelatedPropertyGeneratorsForMaintenanceWindow(gens map[string]gopter.Gen) {
	gens["NotAllowedDates"] = gen.SliceOf(DateSpanGenerator())
	gens["Schedule"] = gen.PtrOf(ScheduleGenerator())
}

func Test_RelativeMonthlySchedule_WhenSerializedToJson_DeserializesAsEqual(t *testing.T) {
	t.Parallel()
	parameters := gopter.DefaultTestParameters()
	parameters.MinSuccessfulTests = 100
	parameters.MaxSize = 3
	properties := gopter.NewProperties(parameters)
	properties.Property(
		"Round trip of RelativeMonthlySchedule via JSON returns original",
		prop.ForAll(RunJSONSerializationTestForRelativeMonthlySchedule, RelativeMonthlyScheduleGenerator()))
	properties.TestingRun(t, gopter.NewFormatedReporter(true, 240, os.Stdout))
}

// RunJSONSerializationTestForRelativeMonthlySchedule runs a test to see if a specific instance of RelativeMonthlySchedule round trips to JSON and back losslessly
func RunJSONSerializationTestForRelativeMonthlySchedule(subject RelativeMonthlySchedule) string {
	// Serialize to JSON
	bin, err := json.Marshal(subject)
	if err != nil {
		return err.Error()
	}

	// Deserialize back into memory
	var actual RelativeMonthlySchedule
	err = json.Unmarshal(bin, &actual)
	if err != nil {
		return err.Error()
	}

	// Check for outcome
	match := cmp.Equal(subject, actual, cmpopts.EquateEmpty())
	if !match {
		actualFmt := pretty.Sprint(actual)
		subjectFmt := pretty.Sprint(subject)
		result := diff.Diff(subjectFmt, actualFmt)
		return result
	}

	return ""
}

// Generator of RelativeMonthlySchedule instances for property testing - lazily instantiated by
// RelativeMonthlyScheduleGenerator()
var relativeMonthlyScheduleGenerator gopter.Gen

// RelativeMonthlyScheduleGenerator returns a generator of RelativeMonthlySchedule instances for property testing.
func RelativeMonthlyScheduleGenerator() gopter.Gen {
	if relativeMonthlyScheduleGenerator != nil {
		return relativeMonthlyScheduleGenerator
	}

	generators := make(map[string]gopter.Gen)
	AddIndependentPropertyGeneratorsForRelativeMonthlySchedule(generators)
	relativeMonthlyScheduleGenerator = gen.Struct(reflect.TypeOf(RelativeMonthlySchedule{}), generators)

	return relativeMonthlyScheduleGenerator
}

// AddIndependentPropertyGeneratorsForRelativeMonthlySchedule is a factory method for creating gopter generators
func AddIndependentPropertyGeneratorsForRelativeMonthlySchedule(gens map[string]gopter.Gen) {
	gens["DayOfWeek"] = gen.PtrOf(gen.OneConstOf(
		WeekDay_Friday,
		WeekDay_Monday,
		WeekDay_Saturday,
		WeekDay_Sunday,
		WeekDay_Thursday,
		WeekDay_Tuesday,
		WeekDay_Wednesday))
	gens["IntervalMonths"] = gen.PtrOf(gen.Int())
	gens["WeekIndex"] = gen.PtrOf(gen.OneConstOf(
		RelativeMonthlySchedule_WeekIndex_First,
		RelativeMonthlySchedule_WeekIndex_Fourth,
		RelativeMonthlySchedule_WeekIndex_Last,
		RelativeMonthlySchedule_WeekIndex_Second,
		RelativeMonthlySchedule_WeekIndex_Third))
}

func Test_Schedule_WhenSerializedToJson_DeserializesAsEqual(t *testing.T) {
	t.Parallel()
	parameters := gopter.DefaultTestParameters()
	parameters.MinSuccessfulTests = 100
	parameters.MaxSize = 3
	properties := gopter.NewProperties(parameters)
	properties.Property(
		"Round trip of Schedule via JSON returns original",
		prop.ForAll(RunJSONSerializationTestForSchedule, ScheduleGenerator()))
	properties.TestingRun(t, gopter.NewFormatedReporter(true, 240, os.Stdout))
}

// RunJSONSerializationTestForSchedule runs a test to see if a specific instance of Schedule round trips to JSON and back losslessly
func RunJSONSerializationTestForSchedule(subject Schedule) string {
	// Serialize to JSON
	bin, err := json.Marshal(subject)
	if err != nil {
		return err.Error()
	}

	// Deserialize back into memory
	var actual Schedule
	err = json.Unmarshal(bin, &actual)
	if err != nil {
		return err.Error()
	}

	// Check for outcome
	match := cmp.Equal(subject, actual, cmpopts.EquateEmpty())
	if !match {
		actualFmt := pretty.Sprint(actual)
		subjectFmt := pretty.Sprint(subject)
		result := diff.Diff(subjectFmt, actualFmt)
		return result
	}

	return ""
}

// Generator of Schedule instances for property testing - lazily instantiated by ScheduleGenerator()
var scheduleGenerator gopter.Gen

// ScheduleGenerator returns a generator of Schedule instances for property testing.
func ScheduleGenerator() gopter.Gen {
	if scheduleGenerator != nil {
		return scheduleGenerator
	}

	generators := make(map[string]gopter.Gen)
	AddRelatedPropertyGeneratorsForSchedule(generators)
	scheduleGenerator = gen.Struct(reflect.TypeOf(Schedule{}), generators)

	return scheduleGenerator
}

// AddRelatedPropertyGeneratorsForSchedule is a factory method for creating gopter generators
func AddRelatedPropertyGeneratorsForSchedule(gens map[string]gopter.Gen) {
	gens["AbsoluteMonthly"] = gen.PtrOf(AbsoluteMonthlyScheduleGenerator())
	gens["Daily"] = gen.PtrOf(DailyScheduleGenerator())
	gens["RelativeMonthly"] = gen.PtrOf(RelativeMonthlyScheduleGenerator())
	gens["Weekly"] = gen.PtrOf(WeeklyScheduleGenerator())
}

func Test_TimeInWeek_WhenSerializedToJson_DeserializesAsEqual(t *testing.T) {
	t.Parallel()
	parameters := gopter.DefaultTestParameters()
	parameters.MinSuccessfulTests = 100
	parameters.MaxSize = 3
	properties := gopter.NewProperties(parameters)
	properties.Property(
		"Round trip of TimeInWeek via JSON returns original",
		prop.ForAll(RunJSONSerializationTestForTimeInWeek, TimeInWeekGenerator()))
	properties.TestingRun(t, gopter.NewFormatedReporter(true, 240, os.Stdout))
}

// RunJSONSerializationTestForTimeInWeek runs a test to see if a specific instance of TimeInWeek round trips to JSON and back losslessly
func RunJSONSerializationTestForTimeInWeek(subject TimeInWeek) string {
	// Serialize to JSON
	bin, err := json.Marshal(subject)
	if err != nil {
		return err.Error()
	}

	// Deserialize back into memory
	var actual TimeInWeek
	err = json.Unmarshal(bin, &actual)
	if err != nil {
		return err.Error()
	}

	// Check for outcome
	match := cmp.Equal(subject, actual, cmpopts.EquateEmpty())
	if !match {
		actualFmt := pretty.Sprint(actual)
		subjectFmt := pretty.Sprint(subject)
		result := diff.Diff(subjectFmt, actualFmt)
		return result
	}

	return ""
}

// Generator of TimeInWeek instances for property testing - lazily instantiated by TimeInWeekGenerator()
var timeInWeekGenerator gopter.Gen

// TimeInWeekGenerator returns a generator of TimeInWeek instances for property testing.
func TimeInWeekGenerator() gopter.Gen {
	if timeInWeekGenerator != nil {
		return timeInWeekGenerator
	}

	generators := make(map[string]gopter.Gen)
	AddIndependentPropertyGeneratorsForTimeInWeek(generators)
	timeInWeekGenerator = gen.Struct(reflect.TypeOf(TimeInWeek{}), generators)

	return timeInWeekGenerator
}

// AddIndependentPropertyGeneratorsForTimeInWeek is a factory method for creating gopter generators
func AddIndependentPropertyGeneratorsForTimeInWeek(gens map[string]gopter.Gen) {
	gens["Day"] = gen.PtrOf(gen.OneConstOf(
		WeekDay_Friday,
		WeekDay_Monday,
		WeekDay_Saturday,
		WeekDay_Sunday,
		WeekDay_Thursday,
		WeekDay_Tuesday,
		WeekDay_Wednesday))
	gens["HourSlots"] = gen.SliceOf(gen.Int())
}

func Test_TimeSpan_WhenSerializedToJson_DeserializesAsEqual(t *testing.T) {
	t.Parallel()
	parameters := gopter.DefaultTestParameters()
	parameters.MinSuccessfulTests = 100
	parameters.MaxSize = 3
	properties := gopter.NewProperties(parameters)
	properties.Property(
		"Round trip of TimeSpan via JSON returns original",
		prop.ForAll(RunJSONSerializationTestForTimeSpan, TimeSpanGenerator()))
	properties.TestingRun(t, gopter.NewFormatedReporter(true, 240, os.Stdout))
}

// RunJSONSerializationTestForTimeSpan runs a test to see if a specific instance of TimeSpan round trips to JSON and back losslessly
func RunJSONSerializationTestForTimeSpan(subject TimeSpan) string {
	// Serialize to JSON
	bin, err := json.Marshal(subject)
	if err != nil {
		return err.Error()
	}

	// Deserialize back into memory
	var actual TimeSpan
	err = json.Unmarshal(bin, &actual)
	if err != nil {
		return err.Error()
	}

	// Check for outcome
	match := cmp.Equal(subject, actual, cmpopts.EquateEmpty())
	if !match {
		actualFmt := pretty.Sprint(actual)
		subjectFmt := pretty.Sprint(subject)
		result := diff.Diff(subjectFmt, actualFmt)
		return result
	}

	return ""
}

// Generator of TimeSpan instances for property testing - lazily instantiated by TimeSpanGenerator()
var timeSpanGenerator gopter.Gen

// TimeSpanGenerator returns a generator of TimeSpan instances for property testing.
func TimeSpanGenerator() gopter.Gen {
	if timeSpanGenerator != nil {
		return timeSpanGenerator
	}

	generators := make(map[string]gopter.Gen)
	AddIndependentPropertyGeneratorsForTimeSpan(generators)
	timeSpanGenerator = gen.Struct(reflect.TypeOf(TimeSpan{}), generators)

	return timeSpanGenerator
}

// AddIndependentPropertyGeneratorsForTimeSpan is a factory method for creating gopter generators
func AddIndependentPropertyGeneratorsForTimeSpan(gens map[string]gopter.Gen) {
	gens["End"] = gen.PtrOf(gen.AlphaString())
	gens["Start"] = gen.PtrOf(gen.AlphaString())
}

func Test_WeeklySchedule_WhenSerializedToJson_DeserializesAsEqual(t *testing.T) {
	t.Parallel()
	parameters := gopter.DefaultTestParameters()
	parameters.MinSuccessfulTests = 100
	parameters.MaxSize = 3
	properties := gopter.NewProperties(parameters)
	properties.Property(
		"Round trip of WeeklySchedule via JSON returns original",
		prop.ForAll(RunJSONSerializationTestForWeeklySchedule, WeeklyScheduleGenerator()))
	properties.TestingRun(t, gopter.NewFormatedReporter(true, 240, os.Stdout))
}

// RunJSONSerializationTestForWeeklySchedule runs a test to see if a specific instance of WeeklySchedule round trips to JSON and back losslessly
func RunJSONSerializationTestForWeeklySchedule(subject WeeklySchedule) string {
	// Serialize to JSON
	bin, err := json.Marshal(subject)
	if err != nil {
		return err.Error()
	}

	// Deserialize back into memory
	var actual WeeklySchedule
	err = json.Unmarshal(bin, &actual)
	if err != nil {
		return err.Error()
	}

	// Check for outcome
	match := cmp.Equal(subject, actual, cmpopts.EquateEmpty())
	if !match {
		actualFmt := pretty.Sprint(actual)
		subjectFmt := pretty.Sprint(subject)
		result := diff.Diff(subjectFmt, actualFmt)
		return result
	}

	return ""
}

// Generator of WeeklySchedule instances for property testing - lazily instantiated by WeeklyScheduleGenerator()
var weeklyScheduleGenerator gopter.Gen

// WeeklyScheduleGenerator returns a generator of WeeklySchedule instances for property testing.
func WeeklyScheduleGenerator() gopter.Gen {
	if weeklyScheduleGenerator != nil {
		return weeklyScheduleGenerator
	}

	generators := make(map[string]gopter.Gen)
	AddIndependentPropertyGeneratorsForWeeklySchedule(generators)
	weeklyScheduleGenerator = gen.Struct(reflect.TypeOf(WeeklySchedule{}), generators)

	return weeklyScheduleGenerator
}

// AddIndependentPropertyGeneratorsForWeeklySchedule is a factory method for creating gopter generators
func AddIndependentPropertyGeneratorsForWeeklySchedule(gens map[string]gopter.Gen) {
	gens["DayOfWeek"] = gen.PtrOf(gen.OneConstOf(
		WeekDay_Friday,
		WeekDay_Monday,
		WeekDay_Saturday,
		WeekDay_Sunday,
		WeekDay_Thursday,
		WeekDay_Tuesday,
		WeekDay_Wednesday))
	gens["IntervalWeeks"] = gen.PtrOf(gen.Int())
}
