<commit_before>/**
 * Copyright 2011-2013 eBusiness Information, Groupe Excilys (www.ebusinessinformation.fr)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 		http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.gatling.core.check

import io.gatling.core.session.{ Expression, Session }
import io.gatling.core.validation.{ FailureWrapper, SuccessWrapper, Validation }

object Validator {
	val foundNothingFailure = "found nothing".failure
}

trait Validator[A] {
	def name: String
	def apply(session: Session, actual: Option[A]): Validation[Option[A]]
}

abstract class Matcher[A, E] extends Validator[A] {
	def expected: Expression[E]
	def doMatch(actual: Option[A], expected: E): Validation[Option[A]]
	def apply(session: Session, actual: Option[A]): Validation[Option[A]] =
		for {
			expected <- expected(session).mapError(message => s"could not resolve expected value: $message")
			matchResult <- doMatch(actual, expected).mapError(message => s"($expected) didn't match: $message")
		} yield matchResult
}

class IsMatcher[X](val expected: Expression[X]) extends Matcher[X, X] {

	val name = "is"

	def doMatch(actual: Option[X], expected: X): Validation[Option[X]] = actual match {
		case Some(actualValue) =>
			if (actualValue == expected)
				actual.success
			else
				s"found $actualValue".failure
		case None => Validator.foundNothingFailure
	}
}

class NotMatcher[X](val expected: Expression[X]) extends Matcher[X, X] {

	val name = "not"

	def doMatch(actual: Option[X], expected: X): Validation[Option[X]] = actual match {
		case Some(actualValue) =>
			if (actualValue != expected)
				actual.success
			else
				s"unexpectedly found $actualValue".failure
		case None => None.success
	}
}

class InMatcher[X](val expected: Expression[Seq[X]]) extends Matcher[X, Seq[X]] {

	val name = "in"

	def doMatch(actual: Option[X], expected: Seq[X]): Validation[Option[X]] = actual match {
		case Some(actualValue) =>
			if (expected.contains(actualValue))
				actual.success
			else
				s"found $actualValue".failure
		case None => Validator.foundNothingFailure
	}
}

class CompareMatcher[X: Ordering](val name: String, message: String, comp: (X, X) => Boolean, val expected: Expression[X]) extends Matcher[X, X] {

	def doMatch(actual: Option[X], expected: X): Validation[Option[X]] = actual.map { actualValue =>
		if (comp(actualValue, expected))
			actual.success
		else
			s"$actualValue is not $message $expected".failure

	}.getOrElse(s"can't compare nothing and $expected".failure)
}

class ExistsValidator[X] extends Validator[X] {
	val name = "exists"
	def apply(session: Session, actual: Option[X]): Validation[Option[X]] = actual match {
		case Some(actualValue) => actual.success
		case None => Validator.foundNothingFailure
	}
}

class NotExistsValidator[X] extends Validator[X] {
	val name = "notExists"
	def apply(session: Session, actual: Option[X]): Validation[Option[X]] = actual match {
		case Some(actualValue) => s"unexpectedly found $actualValue".failure
		case None => None.success
	}
}

class NoopValidator[X] extends Validator[X] {
	val name = "noop"
	def apply(session: Session, actual: Option[X]): Validation[Option[X]] = actual.success
}<commit_msg>minor clean up<commit_after>/**
 * Copyright 2011-2013 eBusiness Information, Groupe Excilys (www.ebusinessinformation.fr)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 		http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.gatling.core.check

import io.gatling.core.session.{ Expression, Session }
import io.gatling.core.validation.{ FailureWrapper, SuccessWrapper, Validation }

object Validator {
	val foundNothingFailure = "found nothing".failure
}

trait Validator[A] {
	def name: String
	def apply(session: Session, actual: Option[A]): Validation[Option[A]]
}

abstract class Matcher[A, E] extends Validator[A] {
	def expected: Expression[E]
	def doMatch(actual: Option[A], expected: E): Validation[Option[A]]
	def apply(session: Session, actual: Option[A]): Validation[Option[A]] =
		for {
			expected <- expected(session).mapError(message => s"could not resolve expected value: $message")
			matchResult <- doMatch(actual, expected).mapError(message => s"($expected) didn't match: $message")
		} yield matchResult
}

class IsMatcher[A](val expected: Expression[A]) extends Matcher[A, A] {

	val name = "is"

	def doMatch(actual: Option[A], expected: A): Validation[Option[A]] = actual match {
		case Some(actualValue) =>
			if (actualValue == expected)
				actual.success
			else
				s"found $actualValue".failure
		case None => Validator.foundNothingFailure
	}
}

class NotMatcher[A](val expected: Expression[A]) extends Matcher[A, A] {

	val name = "not"

	def doMatch(actual: Option[A], expected: A): Validation[Option[A]] = actual match {
		case Some(actualValue) =>
			if (actualValue != expected)
				actual.success
			else
				s"unexpectedly found $actualValue".failure
		case None => None.success
	}
}

class InMatcher[A](val expected: Expression[Seq[A]]) extends Matcher[A, Seq[A]] {

	val name = "in"

	def doMatch(actual: Option[A], expected: Seq[A]): Validation[Option[A]] = actual match {
		case Some(actualValue) =>
			if (expected.contains(actualValue))
				actual.success
			else
				s"found $actualValue".failure
		case None => Validator.foundNothingFailure
	}
}

class CompareMatcher[A: Ordering](val name: String, message: String, comp: (A, A) => Boolean, val expected: Expression[A]) extends Matcher[A, A] {

	def doMatch(actual: Option[A], expected: A): Validation[Option[A]] = actual.map { actualValue =>
		if (comp(actualValue, expected))
			actual.success
		else
			s"$actualValue is not $message $expected".failure

	}.getOrElse(s"can't compare nothing and $expected".failure)
}

class ExistsValidator[A] extends Validator[A] {
	val name = "exists"
	def apply(session: Session, actual: Option[A]): Validation[Option[A]] = actual match {
		case Some(actualValue) => actual.success
		case None => Validator.foundNothingFailure
	}
}

class NotExistsValidator[A] extends Validator[A] {
	val name = "notExists"
	def apply(session: Session, actual: Option[A]): Validation[Option[A]] = actual match {
		case Some(actualValue) => s"unexpectedly found $actualValue".failure
		case None => None.success
	}
}

class NoopValidator[A] extends Validator[A] {
	val name = "noop"
	def apply(session: Session, actual: Option[A]): Validation[Option[A]] = actual.success
}
{'fraction_non_alphanumeric': 0.12501709752427848, 'fraction_numerical': 0.003282724661469019, 'mean_word_length': 4.911075181891674, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, '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': '4626923', 'n_tokens_mistral': 2382, 'n_tokens_neox': 2191, 'n_words': 684}