<commit_before>package httpexpect

import (
	"errors"
	"math"
	"time"
)

// Environment provides a container for arbitrary data shared between tests.
//
// Example:
//
//	env := NewEnvironment(t)
//	env.Put("key", "value")
//	value := env.GetString("key")
type Environment struct {
	chain *chain
	data  map[string]interface{}
}

// NewEnvironment returns a new Environment given a reporter.
//
// Reporter should not be nil.
//
// Example:
//
//	env := NewEnvironment(t)
func NewEnvironment(reporter Reporter) *Environment {
	return newEnvironment(newChainWithDefaults("Environment()", reporter))
}

func newEnvironment(parent *chain) *Environment {
	return &Environment{
		chain: parent.clone(),
		data:  make(map[string]interface{}),
	}
}

// Put saves the value with key in the environment.
//
// Example:
//
//	env := NewEnvironment(t)
//	env.Put("key1", "str")
//	env.Put("key2", 123)
func (e *Environment) Put(key string, value interface{}) {
	e.chain.enter("Put(%q)", key)
	defer e.chain.leave()

	e.data[key] = value
}

// Has returns true if value exists in the environment.
//
// Example:
//
//	if env.Has("key1") {
//	   ...
//	}
func (e *Environment) Has(key string) bool {
	e.chain.enter("Has(%q)", key)
	defer e.chain.leave()

	_, ok := e.data[key]
	return ok
}

// Get returns value stored in the environment.
//
// If value does not exist, reports failure and returns nil.
//
// Example:
//
//	value1 := env.Get("key1").(string)
//	value2 := env.Get("key1").(int)
func (e *Environment) Get(key string) interface{} {
	e.chain.enter("Get(%q)", key)
	defer e.chain.leave()

	value, _ := e.getValue(key)

	return value
}

// GetBool returns value stored in the environment, casted to bool.
//
// If value does not exist, or is not bool, reports failure and returns false.
//
// Example:
//
//	value := env.GetBool("key")
func (e *Environment) GetBool(key string) bool {
	e.chain.enter("GetBool(%q)", key)
	defer e.chain.leave()

	value, ok := e.getValue(key)
	if !ok {
		return false
	}

	casted, ok := value.(bool)
	if !ok {
		e.chain.fail(AssertionFailure{
			Type:   AssertType,
			Actual: &AssertionValue{value},
			Errors: []error{
				errors.New("expected: bool value"),
			},
		})
		return false
	}

	return casted
}

// GetInt returns value stored in the environment, casted to int64.
//
// If value does not exist, or is not signed or unsigned integer that can be
// represented as int without overflow, reports failure and returns zero.
//
// Example:
//
//	value := env.GetInt("key")
func (e *Environment) GetInt(key string) int {
	e.chain.enter("GetInt(%q)", key)
	defer e.chain.leave()

	value, ok := e.getValue(key)
	if !ok {
		return 0
	}

	var casted int

	switch num := value.(type) {
	case int8:
		casted = int(num)
		ok = (int64(num) >= math.MinInt) && (int64(num) <= math.MaxInt)
	case int16:
		casted = int(num)
		ok = (int64(num) >= math.MinInt) && (int64(num) <= math.MaxInt)
	case int32:
		casted = int(num)
		ok = (int64(num) >= math.MinInt) && (int64(num) <= math.MaxInt)
	case int64:
		casted = int(num)
		ok = (int64(num) >= math.MinInt) && (int64(num) <= math.MaxInt)
	case int:
		casted = num
		ok = (int64(num) >= math.MinInt) && (int64(num) <= math.MaxInt)

	case uint8:
		casted = int(num)
		ok = (uint64(num) <= math.MaxInt)
	case uint16:
		casted = int(num)
		ok = (uint64(num) <= math.MaxInt)
	case uint32:
		casted = int(num)
		ok = (uint64(num) <= math.MaxInt)
	case uint64:
		casted = int(num)
		ok = (uint64(num) <= math.MaxInt)
	case uint:
		casted = int(num)
		ok = (uint64(num) <= math.MaxInt)

	default:
		e.chain.fail(AssertionFailure{
			Type:   AssertType,
			Actual: &AssertionValue{value},
			Errors: []error{
				errors.New("expected: signed or unsigned integer"),
			},
		})
		return 0
	}

	if !ok {
		e.chain.fail(AssertionFailure{
			Type:     AssertInRange,
			Actual:   &AssertionValue{value},
			Expected: &AssertionValue{AssertionRange{math.MinInt, math.MaxInt}},
			Errors: []error{
				errors.New(
					"expected: value can be represented as int without overflow"),
			},
		})
		return 0
	}

	return casted
}

// GetFloat returns value stored in the environment, casted to float64.
//
// If value does not exist, or is not floating point value, reports failure
// and returns zero value.
//
// Example:
//
//	value := env.GetFloat("key")
func (e *Environment) GetFloat(key string) float64 {
	e.chain.enter("GetFloat(%q)", key)
	defer e.chain.leave()

	value, ok := e.getValue(key)<commit_msg>Fix compatibility with go 1.14<commit_after>package httpexpect

import (
	"errors"
	"time"
)

// Environment provides a container for arbitrary data shared between tests.
//
// Example:
//
//	env := NewEnvironment(t)
//	env.Put("key", "value")
//	value := env.GetString("key")
type Environment struct {
	chain *chain
	data  map[string]interface{}
}

// NewEnvironment returns a new Environment given a reporter.
//
// Reporter should not be nil.
//
// Example:
//
//	env := NewEnvironment(t)
func NewEnvironment(reporter Reporter) *Environment {
	return newEnvironment(newChainWithDefaults("Environment()", reporter))
}

func newEnvironment(parent *chain) *Environment {
	return &Environment{
		chain: parent.clone(),
		data:  make(map[string]interface{}),
	}
}

// Put saves the value with key in the environment.
//
// Example:
//
//	env := NewEnvironment(t)
//	env.Put("key1", "str")
//	env.Put("key2", 123)
func (e *Environment) Put(key string, value interface{}) {
	e.chain.enter("Put(%q)", key)
	defer e.chain.leave()

	e.data[key] = value
}

// Has returns true if value exists in the environment.
//
// Example:
//
//	if env.Has("key1") {
//	   ...
//	}
func (e *Environment) Has(key string) bool {
	e.chain.enter("Has(%q)", key)
	defer e.chain.leave()

	_, ok := e.data[key]
	return ok
}

// Get returns value stored in the environment.
//
// If value does not exist, reports failure and returns nil.
//
// Example:
//
//	value1 := env.Get("key1").(string)
//	value2 := env.Get("key1").(int)
func (e *Environment) Get(key string) interface{} {
	e.chain.enter("Get(%q)", key)
	defer e.chain.leave()

	value, _ := e.getValue(key)

	return value
}

// GetBool returns value stored in the environment, casted to bool.
//
// If value does not exist, or is not bool, reports failure and returns false.
//
// Example:
//
//	value := env.GetBool("key")
func (e *Environment) GetBool(key string) bool {
	e.chain.enter("GetBool(%q)", key)
	defer e.chain.leave()

	value, ok := e.getValue(key)
	if !ok {
		return false
	}

	casted, ok := value.(bool)
	if !ok {
		e.chain.fail(AssertionFailure{
			Type:   AssertType,
			Actual: &AssertionValue{value},
			Errors: []error{
				errors.New("expected: bool value"),
			},
		})
		return false
	}

	return casted
}

// GetInt returns value stored in the environment, casted to int64.
//
// If value does not exist, or is not signed or unsigned integer that can be
// represented as int without overflow, reports failure and returns zero.
//
// Example:
//
//	value := env.GetInt("key")
func (e *Environment) GetInt(key string) int {
	e.chain.enter("GetInt(%q)", key)
	defer e.chain.leave()

	value, ok := e.getValue(key)
	if !ok {
		return 0
	}

	var casted int

	const (
		intSize = 32 << (^uint(0) >> 63) // 32 or 64
		maxInt  = 1<<(intSize-1) - 1
		minInt  = -1 << (intSize - 1)
	)

	switch num := value.(type) {
	case int8:
		casted = int(num)
		ok = (int64(num) >= minInt) && (int64(num) <= maxInt)
	case int16:
		casted = int(num)
		ok = (int64(num) >= minInt) && (int64(num) <= maxInt)
	case int32:
		casted = int(num)
		ok = (int64(num) >= minInt) && (int64(num) <= maxInt)
	case int64:
		casted = int(num)
		ok = (int64(num) >= minInt) && (int64(num) <= maxInt)
	case int:
		casted = num
		ok = (int64(num) >= minInt) && (int64(num) <= maxInt)

	case uint8:
		casted = int(num)
		ok = (uint64(num) <= maxInt)
	case uint16:
		casted = int(num)
		ok = (uint64(num) <= maxInt)
	case uint32:
		casted = int(num)
		ok = (uint64(num) <= maxInt)
	case uint64:
		casted = int(num)
		ok = (uint64(num) <= maxInt)
	case uint:
		casted = int(num)
		ok = (uint64(num) <= maxInt)

	default:
		e.chain.fail(AssertionFailure{
			Type:   AssertType,
			Actual: &AssertionValue{value},
			Errors: []error{
				errors.New("expected: signed or unsigned integer"),
			},
		})
		return 0
	}

	if !ok {
		e.chain.fail(AssertionFailure{
			Type:     AssertInRange,
			Actual:   &AssertionValue{value},
			Expected: &AssertionValue{AssertionRange{minInt, maxInt}},
			Errors: []error{
				errors.New(
					"expected: value can be represented as int without overflow"),
			},
		})
		return 0
	}

	return casted
}

// GetFloat returns value stored in the environment, casted to float64.
//
// If value does not exist, or is not floating point value, reports failure
// and returns zero value.
//
// Example:
//
//	value := env.GetFloat("key")
func (e *Environment) GetFloat(key string) float64 {
	e.chain.enter("GetFloat(%q)", key)
	defer e.chain.leave()

	value, ok := e.getValue(key)
{'fraction_non_alphanumeric': 0.1651621531260448, 'fraction_numerical': 0.015936698985846428, 'mean_word_length': 3.3436592449177156, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3340192', 'n_tokens_mistral': 3443, 'n_tokens_neox': 3184, 'n_words': 901}