-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce PositionalGenerator (#2710)
* Introduce PositionalGenerator One of the more common complaints among programmers is memorizing and understanding the regular expression syntax. It is concise but dense. The `regexify` method uses a _subset_ of regex language to generate values. Since it is not exactly the Ruby regex language, this means that it is an additional mini-language to learn, with its own quirks. The PositionalGenerator attempts to solve the same problem but more clearly. It is used for generating fixed-length strings where each byte has a specific value, such as postal codes, VINs, business IDs, and so on. Three examples to show the tradeoffs: `gb_licence_checksum` --------------------- With `regexify`: ```ruby regexify(/[0-9][A-Z][A-Z]/) ``` With `PositionalGenerator`: ```ruby generate(:string) do |g| g.int g.letter(ranges: ['A'..'Z'], length: 2) end ``` `ssn_valid` ----------- With `regexify`: ```ruby ssn = regexify(/[0-8]\d{2}-\d{2}-\d{4}/) INVALID_SSN.any? { |regex| regex =~ ssn } ? ssn_valid : ssn ``` With `PositionalGenerator`: ```ruby generate(:string) do |g| g.int(ranges: [100..665, 667..899]) g.lit('-') g.int(ranges: [10..99]) g.lit('-') g.int(ranges: [1000..9999]) end ``` `vin` ----- With `regexify`: ```ruby front = 8.times.map { VIN_KEYSPACE.sample(random: Faker::Config.random) }.join back = 8.times.map { VIN_KEYSPACE.sample(random: Faker::Config.random) }.join checksum = "#{front}A#{back}".chars.each_with_index.map do |char, i| value = (char =~ /\A\d\z/ ? char.to_i : VIN_TRANSLITERATION[char.to_sym]) value * VIN_WEIGHT[i] end.inject(:+) % 11 checksum = 'X' if checksum == 10 "#{front}#{checksum}#{back}" ``` With `PositionalGenerator`: ```ruby generate(:string) do |g| g.letter(name: :wmi, ranges: ['100'..'199', '400'..'499', '500'..'599', '700'..'799', '7A0'..'7F9']) g.letter(name: :vds, length: 5, ranges: [VIN_KEYSPACE]) g.computed(name: :checksum, deps: %i[wmi vds model_year plant_code vis]) do |wmi, vds, model_year, plant_code, vis| checksum = "#{wmi}#{vds}0#{model_year}#{plant_code}#{vis}".chars.each_with_index.map do |char, i| value = (char =~ /\A\d\z/ ? char.to_i : VIN_TRANSLITERATION[char.to_sym]) value * VIN_WEIGHT[i] end.inject(:+) % 11 if checksum == 10 'X' else checksum end end g.letter(name: :model_year, length: 1, ranges: [VIN_KEYSPACE - %w[U Z 0]]) g.letter(name: :plant_code, length: 1, ranges: [VIN_KEYSPACE]) g.int(name: :vis, length: 6) end ``` Summary ------- As you can see, the `PositionalGenerator` is much more verbose than `regexify`. The tradeoff is understanding and readability. * Update lib/helpers/positional_generator.rb Co-authored-by: Mike Burns <mburns@thoughtbot.com> * Apply suggestions from code review Co-authored-by: Thiago Araujo <thd.araujo@gmail.com> * Update lib/helpers/positional_generator.rb Co-authored-by: Mike Burns <mburns@thoughtbot.com> * remove extra space * Update lib/helpers/positional_generator.rb add missing space * Update lib/helpers/positional_generator.rb --------- Co-authored-by: Thiago Araujo <thd.araujo@gmail.com>
- Loading branch information
1 parent
e689abb
commit 1bc565f
Showing
7 changed files
with
628 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.