GameValidator
This gem is a wrapper on 'dry-validation' to validate the entire input in two or more passes.
The first pass will verify only that the user is valid and the player action is valid. If and only if the first pass is successful, a second pass will be made to verify the input against a validator specific to the user's admin status, and to the player_action selected.
Installation
Add this line to your application's Gemfile:
gem 'game_validator'
And then execute:
$ bundle
Or install it yourself as:
$ gem install game_validator
Usage
The base class of this gem is GameValidator::Validator. It requires two dependencies. The first, with key validate_player_action_and_user, is a built in class GameValidator::Validator::Base, while the second, full_validator_for, should be created by the application builder.
validate_player_action_and_user, where the legal player actions are 'run' and 'hide', and the player whose turn it is has an id of 1, is most easily initialized with the below code
GameValidator::Validator::Base::new(legal_options: ['run', 'hide'], next_player_id: 1)
To create the various action specific validators, wrap Dry::Validation::Contract in a manner such as this
class RunValidator
extend Dry::Initializer
option :validate, default: ->{Validator::new}
class Validator < Dry::Validation::Contract
schema do
required(:player_action).filled(:string, eql?: 'run')
required(:where).filled(:string, included_in?: ['here', 'there'])
end
end
class Executor
extend Dry::Initializer
option :where
def call(change_orders:, **args)
change_orders.push(Node::new(where: where))
change_orders
end
end
class Node
extend Dry::Initializer
option :where
def accept(visitor)
visitor.handle_run_node(where)
end
end
def call(input)
result = validate(input)
result.success? ? Executor::new(where: result[:where]) : result
end
end
You then need to arrange all of the possible validators in a hash, with either a String or Hash key the value being the value of player_action, or a two element array as the key, the first element being the string value of player_action, and whether the validator is for an admin or non admin as the second element. If the same validator should apply whether or not the user is an admin or not, the same element should be added twice, with the admin portion being both true and false
full_validator = {
'run' => run_validator,
['hide', true] => hide_admin_validator,
['hide', false] => hide_non_admin_validator # using a hash with two elements as the key in the event I need different validators for admin and non-admin
}
In this fashion, you create the full validator as follows
GameValidator::Validator::new(
validate_player_action_and_user: GameValidator::Validator::Base::new(legal_options: ['run', 'hide'], next_player_id: 1, last_action_id: 1),
full_validator_for: full_validator)
Note the last_action_id option, to make sure that you are validating against the most recent action in the game.
You can also wrap successful results from the validator, using GameValidator::Validator::ValidateToAction and GameValidator::Validator::Result
class DoStuff
def call(change_orders:, **args)
# do stuff
change_orders
end
end
GameValidator::Validator::ValidateToAction::new(
validator: some_regular validator,
wrap: ->(successful_result){GameValidator::Validator::Result::new(
result: successful_result,
execute: DoStuff::new)})
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/game_validator.
License
The gem is available as open source under the terms of the MIT License. extend Dry::Initializer option :where