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

Introduce PositionalGenerator #2710

Merged
merged 7 commits into from
Jul 11, 2023
Merged

Commits on Feb 12, 2023

  1. 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.
    mike-burns committed Feb 12, 2023
    Configuration menu
    Copy the full SHA
    336f82e View commit details
    Browse the repository at this point in the history

Commits on May 31, 2023

  1. Update lib/helpers/positional_generator.rb

    Co-authored-by: Mike Burns <mburns@thoughtbot.com>
    thdaraujo and mike-burns committed May 31, 2023
    Configuration menu
    Copy the full SHA
    48fa4bd View commit details
    Browse the repository at this point in the history

Commits on Jun 9, 2023

  1. Apply suggestions from code review

    Co-authored-by: Thiago Araujo <thd.araujo@gmail.com>
    mike-burns and thdaraujo committed Jun 9, 2023
    Configuration menu
    Copy the full SHA
    8214086 View commit details
    Browse the repository at this point in the history

Commits on Jun 20, 2023

  1. Update lib/helpers/positional_generator.rb

    Co-authored-by: Mike Burns <mburns@thoughtbot.com>
    thdaraujo and mike-burns committed Jun 20, 2023
    Configuration menu
    Copy the full SHA
    6ab0dad View commit details
    Browse the repository at this point in the history

Commits on Jul 2, 2023

  1. remove extra space

    thdaraujo committed Jul 2, 2023
    Configuration menu
    Copy the full SHA
    07aae62 View commit details
    Browse the repository at this point in the history

Commits on Jul 6, 2023

  1. Update lib/helpers/positional_generator.rb

    add missing space
    thdaraujo committed Jul 6, 2023
    Configuration menu
    Copy the full SHA
    ba6635b View commit details
    Browse the repository at this point in the history

Commits on Jul 11, 2023

  1. Configuration menu
    Copy the full SHA
    ab8235d View commit details
    Browse the repository at this point in the history