Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter Generated Values #1836

Open
wants to merge 5 commits into
base: master
from
Open

Filter Generated Values #1836

wants to merge 5 commits into from

Conversation

@tmfnll
Copy link

@tmfnll tmfnll commented Nov 18, 2019

No-Story

Description:

I thought it might be nice to be able to constrain values generated by Faker to some subset of those defined for a given generator.

This PR allows one to invoke select on a generator, passing a block, where the generator will then only output values for which the block evaluates to true.

A contrived example:

Faker::Number.select(&:even?).number

Outputs only even integers.

The same result can be achieved using the equivalent reject method.

I.e. The following is equivalent to the above:

Faker::Number.reject(&:odd?).number

Furthermore, these filters can be a chained after unique constraints:

So

Faker::Number.unique.select(&:even?).reject(&:negative?).number

Returns unique positive integers.

Further details about the implementation can be found in the commit messages.

…esponds_to?

We expect `UniqueGenerator#method_missing` to result in a unique, generated
value whenever the `@generator.public_send(name, arguments)` can be evaluated.

As such, `UniqueGenerator#respond_to_missing?(method)` should return true whenever
`@generator.respond_to?(method)` evaluates to true.
@tmfnll tmfnll changed the title Filter Filter Generated Values Nov 18, 2019

def respond_to_missing?(method_name, include_private = false)
method_name.to_s.start_with?('faker_') || super
@generator.respond_to?(method_name) || super

This comment has been minimized.

@tmfnll

tmfnll Nov 18, 2019
Author

The existing implementation behaves slightly inconsistently:

2.6.3 :005 > Faker::Base.unique.letterify('?')
 => "E" 
2.6.3 :006 > Faker::Base.unique.respond_to? :letterify
 => false 

The change should ensure the above doesn't occur, as well as permit things like following:

2.6.3 :005 > Faker::Base.unique.method :letterify
=> #<Method: Faker::UniqueGenerator#letterify>

(See https://thoughtbot.com/blog/always-define-respond-to-missing-when-overriding)

tmfnll added 4 commits Nov 18, 2019
This works in a similar way to the existing Faker::UniqueGenerator
class in that it keeps trying to generate data up until the point at which
a condition is satisfied.  In this case this condition is provided to
the constructor via a block.
This allows for generators to offer the ability to filter results via `Faker::Filter` objects.

Applying this too the `Faker::Base`, `Faker::UniqueGenerator` and
`Faker::Filter` class means we can mix and match filters with unique constraints.
Include `Faker::Filtering` in `Faker::Filter`, `Faker::UniqueGenerator` and
the extend `Faker::Base`.

This makes `select` and `reject` methods available when generating values.
@tmfnll tmfnll force-pushed the tmfnll:filter branch from 9d22086 to 4f873d3 Nov 19, 2019
@vbrazo vbrazo force-pushed the faker-ruby:master branch from 5a02441 to cc3fbb8 Dec 1, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

1 participant
You can’t perform that action at this time.