govuk_schemas 3.1.0 → 4.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
 - data/.github/dependabot.yml +17 -0
 - data/.rubocop.yml +5 -1
 - data/.ruby-version +1 -1
 - data/CHANGELOG.md +27 -0
 - data/Gemfile +1 -1
 - data/Jenkinsfile +4 -45
 - data/README.md +1 -1
 - data/govuk_schemas.gemspec +7 -8
 - data/lib/govuk_schemas.rb +2 -2
 - data/lib/govuk_schemas/document_types.rb +11 -0
 - data/lib/govuk_schemas/random_content_generator.rb +126 -0
 - data/lib/govuk_schemas/random_example.rb +9 -4
 - data/lib/govuk_schemas/{random_item_generator.rb → random_schema_generator.rb} +49 -34
 - data/lib/govuk_schemas/rspec_matchers.rb +18 -27
 - data/lib/govuk_schemas/schema.rb +2 -3
 - data/lib/govuk_schemas/version.rb +1 -1
 - metadata +24 -24
 - data/lib/govuk_schemas/random.rb +0 -101
 - data/lib/govuk_schemas/utils.rb +0 -16
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 2 
     | 
    
         
            +
            SHA256:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 8123e8bc3461346b31359b47c260930e11505206315aedbfde7532b1601a1e7e
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 3ad819db46a04377edda67d60f3a49c08493723a9b40eefd0d72eade6e1b752c
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: ad57ca91dbe8784fa643ebcab765565480523243fd21829240afc77337da373c0a40d25cfccb4efb225725cc7e40998192d44bb262992170b56fa1aeb38bbe2a
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 2cb1d9f10a775ece8e9143a8de21738484d44f1702c14312da55579c8c0cbbad439b28e0eb554ec840a3c8bee3c551340c3ad5d3efd5273cbf4ad46deaac3afb
         
     | 
| 
         @@ -0,0 +1,17 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            version: 2
         
     | 
| 
      
 2 
     | 
    
         
            +
            updates:
         
     | 
| 
      
 3 
     | 
    
         
            +
              - package-ecosystem: bundler
         
     | 
| 
      
 4 
     | 
    
         
            +
                directory: /
         
     | 
| 
      
 5 
     | 
    
         
            +
                schedule:
         
     | 
| 
      
 6 
     | 
    
         
            +
                  interval: daily
         
     | 
| 
      
 7 
     | 
    
         
            +
                allow:
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # Internal gems
         
     | 
| 
      
 9 
     | 
    
         
            +
                  - dependency-name: "govuk*"
         
     | 
| 
      
 10 
     | 
    
         
            +
                    dependency-type: direct
         
     | 
| 
      
 11 
     | 
    
         
            +
                  - dependency-name: rubocop-govuk
         
     | 
| 
      
 12 
     | 
    
         
            +
                    dependency-type: direct
         
     | 
| 
      
 13 
     | 
    
         
            +
                  # Framework gems
         
     | 
| 
      
 14 
     | 
    
         
            +
                  - dependency-name: rake
         
     | 
| 
      
 15 
     | 
    
         
            +
                    dependency-type: direct
         
     | 
| 
      
 16 
     | 
    
         
            +
                  - dependency-name: rspec
         
     | 
| 
      
 17 
     | 
    
         
            +
                    dependency-type: direct
         
     | 
    
        data/.rubocop.yml
    CHANGED
    
    
    
        data/.ruby-version
    CHANGED
    
    | 
         @@ -1 +1 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            2. 
     | 
| 
      
 1 
     | 
    
         
            +
            2.6.6
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,3 +1,30 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # 4.1.1
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            * Fix RandomSchemaGenerator.new always returning equivalent generators ([#60](https://github.com/alphagov/govuk_schemas/pull/60))
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            # 4.1.0
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            * Add `seed` parameter to `GovukSchemas::RandomExample` to make the random behaviour deterministic. Given the same seed, the same randomised outputs will be returned ([#56](https://github.com/alphagov/govuk_schemas/pull/56)).
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            # 4.0.1
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            * Bump the required Ruby version to >= 2.6.x.
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            # 4.0.0
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            * Change RSpec::Matchers, rename `be_valid_against_schema` to
         
     | 
| 
      
 16 
     | 
    
         
            +
              `be_valid_against_publisher_schema` and add
         
     | 
| 
      
 17 
     | 
    
         
            +
              `be_valid_against_frontend_schema` plus
         
     | 
| 
      
 18 
     | 
    
         
            +
              `be_valid_against_notification_schema`.
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            # 3.3.0
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            * Support generating objects with an `oneOf` property.
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            # 3.2.0
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            * Add `GovukSchemas::DocumentTypes.valid_document_types` (PR #48)
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
       1 
28 
     | 
    
         
             
            # 3.1.0
         
     | 
| 
       2 
29 
     | 
    
         | 
| 
       3 
30 
     | 
    
         
             
            * Update json-schema dependency
         
     | 
    
        data/Gemfile
    CHANGED
    
    
    
        data/Jenkinsfile
    CHANGED
    
    | 
         @@ -1,50 +1,9 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            #!/usr/bin/env groovy
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
      
 3 
     | 
    
         
            +
            library("govuk")
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            node {
         
     | 
| 
       6 
     | 
    
         
            -
               
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
               
     | 
| 
       9 
     | 
    
         
            -
                stage('Checkout') {
         
     | 
| 
       10 
     | 
    
         
            -
                  checkout scm
         
     | 
| 
       11 
     | 
    
         
            -
                }
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
                stage('Clean') {
         
     | 
| 
       14 
     | 
    
         
            -
                  govuk.cleanupGit()
         
     | 
| 
       15 
     | 
    
         
            -
                  govuk.mergeMasterBranch()
         
     | 
| 
       16 
     | 
    
         
            -
                }
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
                stage("Set up content schema dependency") {
         
     | 
| 
       19 
     | 
    
         
            -
                  govuk.contentSchemaDependency()
         
     | 
| 
       20 
     | 
    
         
            -
                }
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                stage('Bundle') {
         
     | 
| 
       23 
     | 
    
         
            -
                  echo 'Bundling'
         
     | 
| 
       24 
     | 
    
         
            -
                  sh("bundle install --path ${JENKINS_HOME}/bundles/${JOB_NAME}")
         
     | 
| 
       25 
     | 
    
         
            -
                }
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
                stage('Linter') {
         
     | 
| 
       28 
     | 
    
         
            -
                  govuk.rubyLinter()
         
     | 
| 
       29 
     | 
    
         
            -
                }
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
                stage('Tests') {
         
     | 
| 
       32 
     | 
    
         
            -
                  govuk.setEnvar('RAILS_ENV', 'test')
         
     | 
| 
       33 
     | 
    
         
            -
                  govuk.runTests('spec')
         
     | 
| 
       34 
     | 
    
         
            -
                }
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
                if(env.BRANCH_NAME == "master") {
         
     | 
| 
       37 
     | 
    
         
            -
                  stage('Publish Gem') {
         
     | 
| 
       38 
     | 
    
         
            -
                    govuk.publishGem(REPOSITORY, env.BRANCH_NAME)
         
     | 
| 
       39 
     | 
    
         
            -
                  }
         
     | 
| 
       40 
     | 
    
         
            -
                }
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
              } catch (e) {
         
     | 
| 
       43 
     | 
    
         
            -
                currentBuild.result = 'FAILED'
         
     | 
| 
       44 
     | 
    
         
            -
                step([$class: 'Mailer',
         
     | 
| 
       45 
     | 
    
         
            -
                      notifyEveryUnstableBuild: true,
         
     | 
| 
       46 
     | 
    
         
            -
                      recipients: 'govuk-ci-notifications@digital.cabinet-office.gov.uk',
         
     | 
| 
       47 
     | 
    
         
            -
                      sendToIndividuals: true])
         
     | 
| 
       48 
     | 
    
         
            -
                throw e
         
     | 
| 
       49 
     | 
    
         
            -
              }
         
     | 
| 
      
 6 
     | 
    
         
            +
              govuk.buildProject(
         
     | 
| 
      
 7 
     | 
    
         
            +
                rubyLintDiff: false,
         
     | 
| 
      
 8 
     | 
    
         
            +
              )
         
     | 
| 
       50 
9 
     | 
    
         
             
            }
         
     | 
    
        data/README.md
    CHANGED
    
    
    
        data/govuk_schemas.gemspec
    CHANGED
    
    | 
         @@ -1,7 +1,6 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
       2 
     | 
    
         
            -
            lib = File.expand_path('../lib', __FILE__)
         
     | 
| 
      
 1 
     | 
    
         
            +
            lib = File.expand_path("lib", __dir__)
         
     | 
| 
       3 
2 
     | 
    
         
             
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         
     | 
| 
       4 
     | 
    
         
            -
            require  
     | 
| 
      
 3 
     | 
    
         
            +
            require "govuk_schemas/version"
         
     | 
| 
       5 
4 
     | 
    
         | 
| 
       6 
5 
     | 
    
         
             
            Gem::Specification.new do |spec|
         
     | 
| 
       7 
6 
     | 
    
         
             
              spec.name          = "govuk_schemas"
         
     | 
| 
         @@ -17,16 +16,16 @@ Gem::Specification.new do |spec| 
     | 
|
| 
       17 
16 
     | 
    
         
             
              spec.files         = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
         
     | 
| 
       18 
17 
     | 
    
         
             
              spec.bindir        = "exe"
         
     | 
| 
       19 
18 
     | 
    
         
             
              spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
         
     | 
| 
       20 
     | 
    
         
            -
              spec.require_paths = [ 
     | 
| 
      
 19 
     | 
    
         
            +
              spec.require_paths = %w[lib]
         
     | 
| 
       21 
20 
     | 
    
         | 
| 
       22 
21 
     | 
    
         
             
              # This should be kept in sync with the json-schema version of govuk-content-schemas.
         
     | 
| 
       23 
22 
     | 
    
         
             
              spec.add_dependency "json-schema", "~> 2.8.0"
         
     | 
| 
       24 
23 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
              spec.add_development_dependency "rake", "~> 10.0"
         
     | 
| 
       26 
     | 
    
         
            -
              spec.add_development_dependency "rspec", "~> 3.4"
         
     | 
| 
       27 
24 
     | 
    
         
             
              spec.add_development_dependency "pry-byebug"
         
     | 
| 
       28 
     | 
    
         
            -
              spec.add_development_dependency " 
     | 
| 
      
 25 
     | 
    
         
            +
              spec.add_development_dependency "rake", "~> 13.0"
         
     | 
| 
      
 26 
     | 
    
         
            +
              spec.add_development_dependency "rspec", "~> 3.4"
         
     | 
| 
      
 27 
     | 
    
         
            +
              spec.add_development_dependency "rubocop-govuk", "~> 3.8"
         
     | 
| 
       29 
28 
     | 
    
         
             
              spec.add_development_dependency "yard", "~> 0.8"
         
     | 
| 
       30 
29 
     | 
    
         | 
| 
       31 
     | 
    
         
            -
              spec.required_ruby_version = ">= 2. 
     | 
| 
      
 30 
     | 
    
         
            +
              spec.required_ruby_version = ">= 2.6"
         
     | 
| 
       32 
31 
     | 
    
         
             
            end
         
     | 
    
        data/lib/govuk_schemas.rb
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require "govuk_schemas/version"
         
     | 
| 
       2 
2 
     | 
    
         
             
            require "govuk_schemas/schema"
         
     | 
| 
       3 
     | 
    
         
            -
            require "govuk_schemas/utils"
         
     | 
| 
       4 
3 
     | 
    
         
             
            require "govuk_schemas/random_example"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "govuk_schemas/document_types"
         
     | 
| 
       5 
5 
     | 
    
         
             
            require "govuk_schemas/example"
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            module GovukSchemas
         
     | 
| 
         @@ -9,6 +9,6 @@ module GovukSchemas 
     | 
|
| 
       9 
9 
     | 
    
         
             
              CONTENT_SCHEMA_DIR = ENV["GOVUK_CONTENT_SCHEMAS_PATH"] || "../govuk-content-schemas"
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
11 
     | 
    
         
             
              # @private
         
     | 
| 
       12 
     | 
    
         
            -
              class InvalidContentGenerated <  
     | 
| 
      
 12 
     | 
    
         
            +
              class InvalidContentGenerated < RuntimeError
         
     | 
| 
       13 
13 
     | 
    
         
             
              end
         
     | 
| 
       14 
14 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,11 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module GovukSchemas
         
     | 
| 
      
 2 
     | 
    
         
            +
              class DocumentTypes
         
     | 
| 
      
 3 
     | 
    
         
            +
                # Return all of the document types on GOV.UK
         
     | 
| 
      
 4 
     | 
    
         
            +
                def self.valid_document_types
         
     | 
| 
      
 5 
     | 
    
         
            +
                  @valid_document_types ||= begin
         
     | 
| 
      
 6 
     | 
    
         
            +
                    filename = "#{GovukSchemas::CONTENT_SCHEMA_DIR}/lib/govuk_content_schemas/allowed_document_types.yml"
         
     | 
| 
      
 7 
     | 
    
         
            +
                    YAML.load_file(filename)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,126 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module GovukSchemas
         
     | 
| 
      
 2 
     | 
    
         
            +
              # @private
         
     | 
| 
      
 3 
     | 
    
         
            +
              class RandomContentGenerator
         
     | 
| 
      
 4 
     | 
    
         
            +
                WORDS = %w[Lorem ipsum dolor sit amet consectetur adipiscing elit. Ut suscipit at mauris non bibendum. Ut ac massa est. Aenean tempor imperdiet leo vel interdum. Nam sagittis cursus sem ultricies scelerisque. Quisque porttitor risus vel risus finibus eu sollicitudin nisl aliquet. Sed sed lectus ac dolor molestie interdum. Nam molestie pellentesque purus ac vestibulum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse non tempor eros. Mauris eu orci hendrerit volutpat lorem in tristique libero. Duis a nibh nibh.].freeze
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                def initialize(random: Random.new)
         
     | 
| 
      
 7 
     | 
    
         
            +
                  @random = random
         
     | 
| 
      
 8 
     | 
    
         
            +
                end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                def string_for_type(type)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  if type == "date-time"
         
     | 
| 
      
 12 
     | 
    
         
            +
                    time
         
     | 
| 
      
 13 
     | 
    
         
            +
                  elsif type == "uri"
         
     | 
| 
      
 14 
     | 
    
         
            +
                    uri
         
     | 
| 
      
 15 
     | 
    
         
            +
                  else
         
     | 
| 
      
 16 
     | 
    
         
            +
                    raise "Unknown attribute type `#{type}`"
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                def time
         
     | 
| 
      
 21 
     | 
    
         
            +
                  arbitrary_time = Time.new(2012, 2, 1)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  (arbitrary_time + @random.rand(0..500_000_000)).iso8601
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                # TODO: make this more random with query string, optional anchor.
         
     | 
| 
      
 26 
     | 
    
         
            +
                def uri
         
     | 
| 
      
 27 
     | 
    
         
            +
                  "http://example.com#{base_path}#{anchor}"
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                def base_path
         
     | 
| 
      
 31 
     | 
    
         
            +
                  "/" + @random.rand(1..5).times.map { uuid }.join("/")
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                def govuk_subdomain_url
         
     | 
| 
      
 35 
     | 
    
         
            +
                  subdomain = @random.rand(2..4).times.map {
         
     | 
| 
      
 36 
     | 
    
         
            +
                    ("a".."z").to_a.sample(@random.rand(3..8), random: @random).join
         
     | 
| 
      
 37 
     | 
    
         
            +
                  }.join(".")
         
     | 
| 
      
 38 
     | 
    
         
            +
                  "https://#{subdomain}.gov.uk#{base_path}"
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                def string(minimum_chars = nil, maximum_chars = nil)
         
     | 
| 
      
 42 
     | 
    
         
            +
                  minimum_chars ||= 0
         
     | 
| 
      
 43 
     | 
    
         
            +
                  maximum_chars ||= 100
         
     | 
| 
      
 44 
     | 
    
         
            +
                  WORDS.sample(@random.rand(minimum_chars..maximum_chars), random: @random).join(" ")
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                def bool
         
     | 
| 
      
 48 
     | 
    
         
            +
                  @random.rand(2) == 1
         
     | 
| 
      
 49 
     | 
    
         
            +
                end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                def anchor
         
     | 
| 
      
 52 
     | 
    
         
            +
                  "##{hex}"
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                def random_identifier(separator:)
         
     | 
| 
      
 56 
     | 
    
         
            +
                  WORDS.sample(@random.rand(1..10), random: @random)
         
     | 
| 
      
 57 
     | 
    
         
            +
                    .join("-")
         
     | 
| 
      
 58 
     | 
    
         
            +
                    .gsub(/[^a-z0-9\-_]+/i, "-")
         
     | 
| 
      
 59 
     | 
    
         
            +
                    .gsub("-", separator)
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                def uuid
         
     | 
| 
      
 63 
     | 
    
         
            +
                  # matches uuid regex e.g. e058aad7-ce86-5181-8801-4ddcb3c8f27c
         
     | 
| 
      
 64 
     | 
    
         
            +
                  # /^[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/
         
     | 
| 
      
 65 
     | 
    
         
            +
                  "#{hex(8)}-#{hex(4)}-1#{hex(3)}-a#{hex(3)}-#{hex(12)}"
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                def hex(length = 10)
         
     | 
| 
      
 69 
     | 
    
         
            +
                  length.times.map { bool ? random_letter : random_number }.join("")
         
     | 
| 
      
 70 
     | 
    
         
            +
                end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                def string_for_regex(pattern)
         
     | 
| 
      
 73 
     | 
    
         
            +
                  case pattern.to_s
         
     | 
| 
      
 74 
     | 
    
         
            +
                  when "^(placeholder|placeholder_.+)$"
         
     | 
| 
      
 75 
     | 
    
         
            +
                    ["placeholder", "placeholder_#{WORDS.sample(random: @random)}"].sample(random: @random)
         
     | 
| 
      
 76 
     | 
    
         
            +
                  when "^[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$"
         
     | 
| 
      
 77 
     | 
    
         
            +
                    uuid
         
     | 
| 
      
 78 
     | 
    
         
            +
                  when "^/(([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})+(/([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})*)*)?$"
         
     | 
| 
      
 79 
     | 
    
         
            +
                    base_path
         
     | 
| 
      
 80 
     | 
    
         
            +
                  when "^[1-9][0-9]{3}[-/](0[1-9]|1[0-2])[-/](0[1-9]|[12][0-9]|3[0-1])$"
         
     | 
| 
      
 81 
     | 
    
         
            +
                    Date.today.iso8601
         
     | 
| 
      
 82 
     | 
    
         
            +
                  when "^[1-9][0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[0-1])$"
         
     | 
| 
      
 83 
     | 
    
         
            +
                    Date.today.iso8601
         
     | 
| 
      
 84 
     | 
    
         
            +
                  when "^#.+$"
         
     | 
| 
      
 85 
     | 
    
         
            +
                    anchor
         
     | 
| 
      
 86 
     | 
    
         
            +
                  when "[a-z-]"
         
     | 
| 
      
 87 
     | 
    
         
            +
                    random_identifier(separator: "-")
         
     | 
| 
      
 88 
     | 
    
         
            +
                  when "^[a-z_]+$"
         
     | 
| 
      
 89 
     | 
    
         
            +
                    random_identifier(separator: "_")
         
     | 
| 
      
 90 
     | 
    
         
            +
                  when "^/(([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})+(/([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})*)*)?(\\?([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})*)?(#([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})*)?$"
         
     | 
| 
      
 91 
     | 
    
         
            +
                    base_path
         
     | 
| 
      
 92 
     | 
    
         
            +
                  when "^https://([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[A-Za-z0-9])?\\.)+campaign\\.gov\\.uk(/(([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})+(/([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})*)*)?(\\?([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})*)?(#([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})*)?)?$"
         
     | 
| 
      
 93 
     | 
    
         
            +
                    govuk_subdomain_url
         
     | 
| 
      
 94 
     | 
    
         
            +
                  when "^https://([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[A-Za-z0-9])?\\.)*gov\\.uk(/(([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})+(/([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})*)*)?(\\?([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})*)?(#([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})*)?)?$"
         
     | 
| 
      
 95 
     | 
    
         
            +
                    govuk_subdomain_url
         
     | 
| 
      
 96 
     | 
    
         
            +
                  when '[a-z0-9\-_]'
         
     | 
| 
      
 97 
     | 
    
         
            +
                    "#{hex}-#{hex}"
         
     | 
| 
      
 98 
     | 
    
         
            +
                  else
         
     | 
| 
      
 99 
     | 
    
         
            +
                    raise <<-DOC
         
     | 
| 
      
 100 
     | 
    
         
            +
                      Don't know how to generate random string for pattern #{pattern.inspect}
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                      This propably means you've introduced a new regex in  govuk-content-schemas.
         
     | 
| 
      
 103 
     | 
    
         
            +
                      Because it's very hard to generate a valid string from a regex alone,
         
     | 
| 
      
 104 
     | 
    
         
            +
                      we have to specify a method to generate random data for each regex in
         
     | 
| 
      
 105 
     | 
    
         
            +
                      the schemas.
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                      To fix this:
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
                      - Add your regex to `lib/govuk_schemas/random.rb`
         
     | 
| 
      
 110 
     | 
    
         
            +
                    DOC
         
     | 
| 
      
 111 
     | 
    
         
            +
                  end
         
     | 
| 
      
 112 
     | 
    
         
            +
                end
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
              private
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
                def random_letter
         
     | 
| 
      
 117 
     | 
    
         
            +
                  letters = ("a".."f").to_a
         
     | 
| 
      
 118 
     | 
    
         
            +
                  letters[@random.rand(0..letters.count - 1)]
         
     | 
| 
      
 119 
     | 
    
         
            +
                end
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                def random_number
         
     | 
| 
      
 122 
     | 
    
         
            +
                  numbers = ("0".."9").to_a
         
     | 
| 
      
 123 
     | 
    
         
            +
                  numbers[@random.rand(0..numbers.count - 1)]
         
     | 
| 
      
 124 
     | 
    
         
            +
                end
         
     | 
| 
      
 125 
     | 
    
         
            +
              end
         
     | 
| 
      
 126 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,5 +1,4 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require "govuk_schemas/ 
     | 
| 
       2 
     | 
    
         
            -
            require "govuk_schemas/random_item_generator"
         
     | 
| 
      
 1 
     | 
    
         
            +
            require "govuk_schemas/random_schema_generator"
         
     | 
| 
       3 
2 
     | 
    
         
             
            require "json-schema"
         
     | 
| 
       4 
3 
     | 
    
         
             
            require "json"
         
     | 
| 
       5 
4 
     | 
    
         | 
| 
         @@ -24,11 +23,17 @@ module GovukSchemas 
     | 
|
| 
       24 
23 
     | 
    
         
             
                #     schema = GovukSchemas::Schema.find(frontend_schema: "detailed_guide")
         
     | 
| 
       25 
24 
     | 
    
         
             
                #     GovukSchemas::RandomExample.new(schema: schema).payload
         
     | 
| 
       26 
25 
     | 
    
         
             
                #
         
     | 
| 
      
 26 
     | 
    
         
            +
                # Example with seed (for consistent results):
         
     | 
| 
      
 27 
     | 
    
         
            +
                #
         
     | 
| 
      
 28 
     | 
    
         
            +
                #     schema = GovukSchemas::Schema.find(frontend_schema: "detailed_guide")
         
     | 
| 
      
 29 
     | 
    
         
            +
                #     GovukSchemas::RandomExample.new(schema: schema, seed: 777).payload
         
     | 
| 
      
 30 
     | 
    
         
            +
                #     GovukSchemas::RandomExample.new(schema: schema, seed: 777).payload # returns same as above
         
     | 
| 
      
 31 
     | 
    
         
            +
                #
         
     | 
| 
       27 
32 
     | 
    
         
             
                # @param [Hash] schema A JSON schema.
         
     | 
| 
       28 
33 
     | 
    
         
             
                # @return [GovukSchemas::RandomExample]
         
     | 
| 
       29 
     | 
    
         
            -
                def initialize(schema:)
         
     | 
| 
      
 34 
     | 
    
         
            +
                def initialize(schema:, seed: nil)
         
     | 
| 
       30 
35 
     | 
    
         
             
                  @schema = schema
         
     | 
| 
       31 
     | 
    
         
            -
                  @random_generator =  
     | 
| 
      
 36 
     | 
    
         
            +
                  @random_generator = RandomSchemaGenerator.new(schema: schema, seed: seed)
         
     | 
| 
       32 
37 
     | 
    
         
             
                end
         
     | 
| 
       33 
38 
     | 
    
         | 
| 
       34 
39 
     | 
    
         
             
                # Returns a new `GovukSchemas::RandomExample` object.
         
     | 
| 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require "govuk_schemas/ 
     | 
| 
      
 1 
     | 
    
         
            +
            require "govuk_schemas/random_content_generator"
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            module GovukSchemas
         
     | 
| 
       4 
     | 
    
         
            -
              # The  
     | 
| 
      
 4 
     | 
    
         
            +
              # The RandomSchemaGenerator takes a JSON schema and outputs a random hash that
         
     | 
| 
       5 
5 
     | 
    
         
             
              # is valid against said schema.
         
     | 
| 
       6 
6 
     | 
    
         
             
              #
         
     | 
| 
       7 
7 
     | 
    
         
             
              # The "randomness" here is quote relative, it's particularly tailored to the
         
     | 
| 
         @@ -9,9 +9,11 @@ module GovukSchemas 
     | 
|
| 
       9 
9 
     | 
    
         
             
              # hundred characters to keep the resulting items small.
         
     | 
| 
       10 
10 
     | 
    
         
             
              #
         
     | 
| 
       11 
11 
     | 
    
         
             
              # @private
         
     | 
| 
       12 
     | 
    
         
            -
              class  
     | 
| 
       13 
     | 
    
         
            -
                def initialize(schema:)
         
     | 
| 
      
 12 
     | 
    
         
            +
              class RandomSchemaGenerator
         
     | 
| 
      
 13 
     | 
    
         
            +
                def initialize(schema:, seed: nil)
         
     | 
| 
       14 
14 
     | 
    
         
             
                  @schema = schema
         
     | 
| 
      
 15 
     | 
    
         
            +
                  @random = Random.new(seed || Random.new_seed)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  @generator = RandomContentGenerator.new(random: @random)
         
     | 
| 
       15 
17 
     | 
    
         
             
                end
         
     | 
| 
       16 
18 
     | 
    
         | 
| 
       17 
19 
     | 
    
         
             
                def payload
         
     | 
| 
         @@ -24,45 +26,45 @@ module GovukSchemas 
     | 
|
| 
       24 
26 
     | 
    
         
             
                  # TODO: #/definitions/nested_headers are recursively nested and can cause
         
     | 
| 
       25 
27 
     | 
    
         
             
                  # infinite loops. We need to add something that detects and prevents the
         
     | 
| 
       26 
28 
     | 
    
         
             
                  # loop. In the meantime return a valid value.
         
     | 
| 
       27 
     | 
    
         
            -
                  if props[ 
     | 
| 
      
 29 
     | 
    
         
            +
                  if props["$ref"] == "#/definitions/nested_headers"
         
     | 
| 
       28 
30 
     | 
    
         
             
                    return [{ "text" => "1", "level" => 1, "id" => "ABC" }]
         
     | 
| 
       29 
31 
     | 
    
         
             
                  end
         
     | 
| 
       30 
32 
     | 
    
         | 
| 
       31 
33 
     | 
    
         
             
                  # JSON schemas can have "pointers". We use this to extract defintions and
         
     | 
| 
       32 
34 
     | 
    
         
             
                  # reduce duplication. To make the schema easily parsable we inline the
         
     | 
| 
       33 
35 
     | 
    
         
             
                  # reference here.
         
     | 
| 
       34 
     | 
    
         
            -
                  if props[ 
     | 
| 
       35 
     | 
    
         
            -
                    props.merge!(lookup_json_pointer(props[ 
     | 
| 
      
 36 
     | 
    
         
            +
                  if props["$ref"]
         
     | 
| 
      
 37 
     | 
    
         
            +
                    props.merge!(lookup_json_pointer(props["$ref"]))
         
     | 
| 
       36 
38 
     | 
    
         
             
                  end
         
     | 
| 
       37 
39 
     | 
    
         | 
| 
       38 
40 
     | 
    
         
             
                  # Attributes with `enum` specified often omit the `type` from
         
     | 
| 
       39 
41 
     | 
    
         
             
                  # their definition. It's most likely a string.
         
     | 
| 
       40 
     | 
    
         
            -
                  type = props[ 
     | 
| 
      
 42 
     | 
    
         
            +
                  type = props["type"] || "string"
         
     | 
| 
       41 
43 
     | 
    
         | 
| 
       42 
44 
     | 
    
         
             
                  # Except when it has properties, because it's defintely an object then.
         
     | 
| 
       43 
     | 
    
         
            -
                  if props[ 
     | 
| 
      
 45 
     | 
    
         
            +
                  if props["properties"]
         
     | 
| 
       44 
46 
     | 
    
         
             
                    type = "object"
         
     | 
| 
       45 
47 
     | 
    
         
             
                  end
         
     | 
| 
       46 
48 
     | 
    
         | 
| 
       47 
49 
     | 
    
         
             
                  # Make sure that we choose a type when there are more than one specified.
         
     | 
| 
       48 
     | 
    
         
            -
                  type = Array(type).sample
         
     | 
| 
      
 50 
     | 
    
         
            +
                  type = Array(type).sample(random: @random)
         
     | 
| 
       49 
51 
     | 
    
         | 
| 
       50 
     | 
    
         
            -
                  if props[ 
     | 
| 
       51 
     | 
    
         
            -
                    generate_value(props[ 
     | 
| 
       52 
     | 
    
         
            -
                  elsif props[ 
     | 
| 
      
 52 
     | 
    
         
            +
                  if props["anyOf"]
         
     | 
| 
      
 53 
     | 
    
         
            +
                    generate_value(props["anyOf"].sample(random: @random))
         
     | 
| 
      
 54 
     | 
    
         
            +
                  elsif props["oneOf"] && type != "object"
         
     | 
| 
       53 
55 
     | 
    
         
             
                    # FIXME: Generating valid data for a `oneOf` schema is quite interesting.
         
     | 
| 
       54 
56 
     | 
    
         
             
                    # According to the JSON Schema spec a `oneOf` schema is only valid if
         
     | 
| 
       55 
57 
     | 
    
         
             
                    # the data is valid against *only one* of the clauses. To do this
         
     | 
| 
       56 
58 
     | 
    
         
             
                    # properly, we'd have to verify that the data generated below doesn't
         
     | 
| 
       57 
59 
     | 
    
         
             
                    # validate against the other schemas in `props['oneOf']`.
         
     | 
| 
       58 
     | 
    
         
            -
                    generate_value(props[ 
     | 
| 
       59 
     | 
    
         
            -
                  elsif props[ 
     | 
| 
       60 
     | 
    
         
            -
                    props[ 
     | 
| 
      
 60 
     | 
    
         
            +
                    generate_value(props["oneOf"].sample(random: @random))
         
     | 
| 
      
 61 
     | 
    
         
            +
                  elsif props["allOf"]
         
     | 
| 
      
 62 
     | 
    
         
            +
                    props["allOf"].each_with_object({}) do |subschema, hash|
         
     | 
| 
       61 
63 
     | 
    
         
             
                      val = generate_value(subschema)
         
     | 
| 
       62 
64 
     | 
    
         
             
                      hash.merge(val)
         
     | 
| 
       63 
65 
     | 
    
         
             
                    end
         
     | 
| 
       64 
     | 
    
         
            -
                  elsif props[ 
     | 
| 
       65 
     | 
    
         
            -
                    props[ 
     | 
| 
      
 66 
     | 
    
         
            +
                  elsif props["enum"]
         
     | 
| 
      
 67 
     | 
    
         
            +
                    props["enum"].sample(random: @random)
         
     | 
| 
       66 
68 
     | 
    
         
             
                  elsif type == "null"
         
     | 
| 
       67 
69 
     | 
    
         
             
                    nil
         
     | 
| 
       68 
70 
     | 
    
         
             
                  elsif type == "object"
         
     | 
| 
         @@ -70,11 +72,11 @@ module GovukSchemas 
     | 
|
| 
       70 
72 
     | 
    
         
             
                  elsif type == "array"
         
     | 
| 
       71 
73 
     | 
    
         
             
                    generate_random_array(props)
         
     | 
| 
       72 
74 
     | 
    
         
             
                  elsif type == "boolean"
         
     | 
| 
       73 
     | 
    
         
            -
                     
     | 
| 
      
 75 
     | 
    
         
            +
                    @generator.bool
         
     | 
| 
       74 
76 
     | 
    
         
             
                  elsif type == "integer"
         
     | 
| 
       75 
     | 
    
         
            -
                    min = props[ 
     | 
| 
       76 
     | 
    
         
            -
                    max = props[ 
     | 
| 
       77 
     | 
    
         
            -
                    rand(min..max)
         
     | 
| 
      
 77 
     | 
    
         
            +
                    min = props["minimum"] || 0
         
     | 
| 
      
 78 
     | 
    
         
            +
                    max = props["maximum"] || 10
         
     | 
| 
      
 79 
     | 
    
         
            +
                    @random.rand(min..max)
         
     | 
| 
       78 
80 
     | 
    
         
             
                  elsif type == "string"
         
     | 
| 
       79 
81 
     | 
    
         
             
                    generate_random_string(props)
         
     | 
| 
       80 
82 
     | 
    
         
             
                  else
         
     | 
| 
         @@ -85,43 +87,56 @@ module GovukSchemas 
     | 
|
| 
       85 
87 
     | 
    
         
             
                def generate_random_object(subschema)
         
     | 
| 
       86 
88 
     | 
    
         
             
                  document = {}
         
     | 
| 
       87 
89 
     | 
    
         | 
| 
       88 
     | 
    
         
            -
                  ( 
     | 
| 
      
 90 
     | 
    
         
            +
                  one_of_sample = subschema.fetch("oneOf", []).sample(random: @random) || {}
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                  (subschema["properties"] || {}).each do |attribute_name, attribute_properties|
         
     | 
| 
       89 
93 
     | 
    
         
             
                    # TODO: When the schema contains `subschema['minProperties']` we always
         
     | 
| 
       90 
94 
     | 
    
         
             
                    # populate all of the keys in the hash. This isn't quite random, but I
         
     | 
| 
       91 
95 
     | 
    
         
             
                    # haven't found a nice way yet to ensure there's at least n elements in
         
     | 
| 
       92 
96 
     | 
    
         
             
                    # the hash.
         
     | 
| 
       93 
     | 
    
         
            -
                     
     | 
| 
       94 
     | 
    
         
            -
                       
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
      
 97 
     | 
    
         
            +
                    should_generate_value = @generator.bool \
         
     | 
| 
      
 98 
     | 
    
         
            +
                      || subschema["required"].to_a.include?(attribute_name) \
         
     | 
| 
      
 99 
     | 
    
         
            +
                      || (one_of_sample["required"] || {}).to_a.include?(attribute_name) \
         
     | 
| 
      
 100 
     | 
    
         
            +
                      || (one_of_sample["properties"] || {}).keys.include?(attribute_name) \
         
     | 
| 
      
 101 
     | 
    
         
            +
                      || subschema["minProperties"] \
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
                    next unless should_generate_value
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
                    one_of_properties = (one_of_sample["properties"] || {})[attribute_name]
         
     | 
| 
      
 106 
     | 
    
         
            +
                    document[attribute_name] = if one_of_properties
         
     | 
| 
      
 107 
     | 
    
         
            +
                                                 generate_value(one_of_properties)
         
     | 
| 
      
 108 
     | 
    
         
            +
                                               else
         
     | 
| 
      
 109 
     | 
    
         
            +
                                                 generate_value(attribute_properties)
         
     | 
| 
      
 110 
     | 
    
         
            +
                                               end
         
     | 
| 
       96 
111 
     | 
    
         
             
                  end
         
     | 
| 
       97 
112 
     | 
    
         | 
| 
       98 
113 
     | 
    
         
             
                  document
         
     | 
| 
       99 
114 
     | 
    
         
             
                end
         
     | 
| 
       100 
115 
     | 
    
         | 
| 
       101 
116 
     | 
    
         
             
                def generate_random_array(props)
         
     | 
| 
       102 
     | 
    
         
            -
                  min = props[ 
     | 
| 
       103 
     | 
    
         
            -
                  max = props[ 
     | 
| 
       104 
     | 
    
         
            -
                  num_items = rand(min..max)
         
     | 
| 
      
 117 
     | 
    
         
            +
                  min = props["minItems"] || 0
         
     | 
| 
      
 118 
     | 
    
         
            +
                  max = props["maxItems"] || 10
         
     | 
| 
      
 119 
     | 
    
         
            +
                  num_items = @random.rand(min..max)
         
     | 
| 
       105 
120 
     | 
    
         | 
| 
       106 
121 
     | 
    
         
             
                  num_items.times.map do
         
     | 
| 
       107 
122 
     | 
    
         
             
                    # sometimes arrays don't have `items` specified, not sure if this is a bug
         
     | 
| 
       108 
     | 
    
         
            -
                    generate_value(props[ 
     | 
| 
      
 123 
     | 
    
         
            +
                    generate_value(props["items"] || {})
         
     | 
| 
       109 
124 
     | 
    
         
             
                  end
         
     | 
| 
       110 
125 
     | 
    
         
             
                end
         
     | 
| 
       111 
126 
     | 
    
         | 
| 
       112 
127 
     | 
    
         
             
                def generate_random_string(props)
         
     | 
| 
       113 
128 
     | 
    
         
             
                  if props["format"]
         
     | 
| 
       114 
     | 
    
         
            -
                     
     | 
| 
      
 129 
     | 
    
         
            +
                    @generator.string_for_type(props["format"])
         
     | 
| 
       115 
130 
     | 
    
         
             
                  elsif props["pattern"]
         
     | 
| 
       116 
     | 
    
         
            -
                     
     | 
| 
      
 131 
     | 
    
         
            +
                    @generator.string_for_regex(props["pattern"])
         
     | 
| 
       117 
132 
     | 
    
         
             
                  else
         
     | 
| 
       118 
     | 
    
         
            -
                     
     | 
| 
      
 133 
     | 
    
         
            +
                    @generator.string(props["minLength"], props["maxLength"])
         
     | 
| 
       119 
134 
     | 
    
         
             
                  end
         
     | 
| 
       120 
135 
     | 
    
         
             
                end
         
     | 
| 
       121 
136 
     | 
    
         | 
| 
       122 
137 
     | 
    
         
             
                # Look up a "pointer" like "#/definitions/title" in the schema.
         
     | 
| 
       123 
138 
     | 
    
         
             
                def lookup_json_pointer(ref)
         
     | 
| 
       124 
     | 
    
         
            -
                  elements = ref.split( 
     | 
| 
      
 139 
     | 
    
         
            +
                  elements = ref.split("/")
         
     | 
| 
       125 
140 
     | 
    
         
             
                  elements.shift
         
     | 
| 
       126 
141 
     | 
    
         
             
                  @schema.dig(*elements) || raise("Definition `#{ref}` not found in the schema")
         
     | 
| 
       127 
142 
     | 
    
         
             
                end
         
     | 
| 
         @@ -1,26 +1,16 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module GovukSchemas
         
     | 
| 
       2 
2 
     | 
    
         
             
              module RSpecMatchers
         
     | 
| 
       3 
     | 
    
         
            -
                 
     | 
| 
       4 
     | 
    
         
            -
                   
     | 
| 
       5 
     | 
    
         
            -
                     
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
                     
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
                RSpec::Matchers.define :be_valid_against_links_schema do |schema_name|
         
     | 
| 
       16 
     | 
    
         
            -
                  match do |item|
         
     | 
| 
       17 
     | 
    
         
            -
                    schema = Schema.find(links_schema: schema_name)
         
     | 
| 
       18 
     | 
    
         
            -
                    validator = JSON::Validator.fully_validate(schema, item)
         
     | 
| 
       19 
     | 
    
         
            -
                    validator.empty?
         
     | 
| 
       20 
     | 
    
         
            -
                  end
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                  failure_message do |actual|
         
     | 
| 
       23 
     | 
    
         
            -
                    ValidationErrorMessage.new(schema_name, "links", actual).message
         
     | 
| 
      
 3 
     | 
    
         
            +
                %w[links frontend publisher notification].each do |schema_type|
         
     | 
| 
      
 4 
     | 
    
         
            +
                  RSpec::Matchers.define "be_valid_against_#{schema_type}_schema".to_sym do |schema_name|
         
     | 
| 
      
 5 
     | 
    
         
            +
                    match do |item|
         
     | 
| 
      
 6 
     | 
    
         
            +
                      schema = Schema.find(Hash["#{schema_type}_schema".to_sym, schema_name])
         
     | 
| 
      
 7 
     | 
    
         
            +
                      validator = JSON::Validator.fully_validate(schema, item)
         
     | 
| 
      
 8 
     | 
    
         
            +
                      validator.empty?
         
     | 
| 
      
 9 
     | 
    
         
            +
                    end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                    failure_message do |actual|
         
     | 
| 
      
 12 
     | 
    
         
            +
                      ValidationErrorMessage.new(schema_name, "schema", actual).message
         
     | 
| 
      
 13 
     | 
    
         
            +
                    end
         
     | 
| 
       24 
14 
     | 
    
         
             
                  end
         
     | 
| 
       25 
15 
     | 
    
         
             
                end
         
     | 
| 
       26 
16 
     | 
    
         
             
              end
         
     | 
| 
         @@ -36,14 +26,14 @@ module GovukSchemas 
     | 
|
| 
       36 
26 
     | 
    
         
             
                end
         
     | 
| 
       37 
27 
     | 
    
         | 
| 
       38 
28 
     | 
    
         
             
                def message
         
     | 
| 
       39 
     | 
    
         
            -
                  <<~ 
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
      
 29 
     | 
    
         
            +
                  <<~DOC
         
     | 
| 
      
 30 
     | 
    
         
            +
                    expected the payload to be valid against the '#{schema_name}' schema:
         
     | 
| 
       41 
31 
     | 
    
         | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
      
 32 
     | 
    
         
            +
                    #{formatted_payload}
         
     | 
| 
       43 
33 
     | 
    
         | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
                   
     | 
| 
      
 34 
     | 
    
         
            +
                    Validation errors:
         
     | 
| 
      
 35 
     | 
    
         
            +
                    #{errors}
         
     | 
| 
      
 36 
     | 
    
         
            +
                  DOC
         
     | 
| 
       47 
37 
     | 
    
         
             
                end
         
     | 
| 
       48 
38 
     | 
    
         | 
| 
       49 
39 
     | 
    
         
             
              private
         
     | 
| 
         @@ -56,6 +46,7 @@ module GovukSchemas 
     | 
|
| 
       56 
46 
     | 
    
         | 
| 
       57 
47 
     | 
    
         
             
                def formatted_payload
         
     | 
| 
       58 
48 
     | 
    
         
             
                  return payload if payload.is_a?(String)
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
       59 
50 
     | 
    
         
             
                  JSON.pretty_generate(payload)
         
     | 
| 
       60 
51 
     | 
    
         
             
                end
         
     | 
| 
       61 
52 
     | 
    
         | 
    
        data/lib/govuk_schemas/schema.rb
    CHANGED
    
    | 
         @@ -19,11 +19,10 @@ module GovukSchemas 
     | 
|
| 
       19 
19 
     | 
    
         
             
                #
         
     | 
| 
       20 
20 
     | 
    
         
             
                # @param schema_type [String] The type: frontend, publisher, notification or links
         
     | 
| 
       21 
21 
     | 
    
         
             
                # @return [Array<Hash>] List of JSON schemas as hashes
         
     | 
| 
       22 
     | 
    
         
            -
                def self.all(schema_type:  
     | 
| 
      
 22 
     | 
    
         
            +
                def self.all(schema_type: "*")
         
     | 
| 
       23 
23 
     | 
    
         
             
                  schema_type = "publisher_v2" if schema_type == "publisher"
         
     | 
| 
       24 
     | 
    
         
            -
                  Dir.glob("#{GovukSchemas::CONTENT_SCHEMA_DIR}/dist/formats/*/#{schema_type}/*.json"). 
     | 
| 
      
 24 
     | 
    
         
            +
                  Dir.glob("#{GovukSchemas::CONTENT_SCHEMA_DIR}/dist/formats/*/#{schema_type}/*.json").each_with_object({}) do |file_path, hash|
         
     | 
| 
       25 
25 
     | 
    
         
             
                    hash[file_path] = JSON.parse(File.read(file_path))
         
     | 
| 
       26 
     | 
    
         
            -
                    hash
         
     | 
| 
       27 
26 
     | 
    
         
             
                  end
         
     | 
| 
       28 
27 
     | 
    
         
             
                end
         
     | 
| 
       29 
28 
     | 
    
         | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: govuk_schemas
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version:  
     | 
| 
      
 4 
     | 
    
         
            +
              version: 4.1.1
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - GOV.UK Dev
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: exe
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date:  
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2020-08-17 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: json-schema
         
     | 
| 
         @@ -25,61 +25,61 @@ dependencies: 
     | 
|
| 
       25 
25 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       26 
26 
     | 
    
         
             
                    version: 2.8.0
         
     | 
| 
       27 
27 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       28 
     | 
    
         
            -
              name:  
     | 
| 
      
 28 
     | 
    
         
            +
              name: pry-byebug
         
     | 
| 
       29 
29 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       30 
30 
     | 
    
         
             
                requirements:
         
     | 
| 
       31 
     | 
    
         
            -
                - - " 
     | 
| 
      
 31 
     | 
    
         
            +
                - - ">="
         
     | 
| 
       32 
32 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       33 
     | 
    
         
            -
                    version: ' 
     | 
| 
      
 33 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
       34 
34 
     | 
    
         
             
              type: :development
         
     | 
| 
       35 
35 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       36 
36 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       37 
37 
     | 
    
         
             
                requirements:
         
     | 
| 
       38 
     | 
    
         
            -
                - - " 
     | 
| 
      
 38 
     | 
    
         
            +
                - - ">="
         
     | 
| 
       39 
39 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       40 
     | 
    
         
            -
                    version: ' 
     | 
| 
      
 40 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
       41 
41 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       42 
     | 
    
         
            -
              name:  
     | 
| 
      
 42 
     | 
    
         
            +
              name: rake
         
     | 
| 
       43 
43 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       44 
44 
     | 
    
         
             
                requirements:
         
     | 
| 
       45 
45 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       46 
46 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       47 
     | 
    
         
            -
                    version: ' 
     | 
| 
      
 47 
     | 
    
         
            +
                    version: '13.0'
         
     | 
| 
       48 
48 
     | 
    
         
             
              type: :development
         
     | 
| 
       49 
49 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       50 
50 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       51 
51 
     | 
    
         
             
                requirements:
         
     | 
| 
       52 
52 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       53 
53 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       54 
     | 
    
         
            -
                    version: ' 
     | 
| 
      
 54 
     | 
    
         
            +
                    version: '13.0'
         
     | 
| 
       55 
55 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       56 
     | 
    
         
            -
              name:  
     | 
| 
      
 56 
     | 
    
         
            +
              name: rspec
         
     | 
| 
       57 
57 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       58 
58 
     | 
    
         
             
                requirements:
         
     | 
| 
       59 
     | 
    
         
            -
                - - " 
     | 
| 
      
 59 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
       60 
60 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       61 
     | 
    
         
            -
                    version: ' 
     | 
| 
      
 61 
     | 
    
         
            +
                    version: '3.4'
         
     | 
| 
       62 
62 
     | 
    
         
             
              type: :development
         
     | 
| 
       63 
63 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       64 
64 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       65 
65 
     | 
    
         
             
                requirements:
         
     | 
| 
       66 
     | 
    
         
            -
                - - " 
     | 
| 
      
 66 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
       67 
67 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       68 
     | 
    
         
            -
                    version: ' 
     | 
| 
      
 68 
     | 
    
         
            +
                    version: '3.4'
         
     | 
| 
       69 
69 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       70 
     | 
    
         
            -
              name: govuk 
     | 
| 
      
 70 
     | 
    
         
            +
              name: rubocop-govuk
         
     | 
| 
       71 
71 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       72 
72 
     | 
    
         
             
                requirements:
         
     | 
| 
       73 
73 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       74 
74 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       75 
     | 
    
         
            -
                    version:  
     | 
| 
      
 75 
     | 
    
         
            +
                    version: '3.8'
         
     | 
| 
       76 
76 
     | 
    
         
             
              type: :development
         
     | 
| 
       77 
77 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       78 
78 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       79 
79 
     | 
    
         
             
                requirements:
         
     | 
| 
       80 
80 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       81 
81 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       82 
     | 
    
         
            -
                    version:  
     | 
| 
      
 82 
     | 
    
         
            +
                    version: '3.8'
         
     | 
| 
       83 
83 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       84 
84 
     | 
    
         
             
              name: yard
         
     | 
| 
       85 
85 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -101,6 +101,7 @@ executables: [] 
     | 
|
| 
       101 
101 
     | 
    
         
             
            extensions: []
         
     | 
| 
       102 
102 
     | 
    
         
             
            extra_rdoc_files: []
         
     | 
| 
       103 
103 
     | 
    
         
             
            files:
         
     | 
| 
      
 104 
     | 
    
         
            +
            - ".github/dependabot.yml"
         
     | 
| 
       104 
105 
     | 
    
         
             
            - ".gitignore"
         
     | 
| 
       105 
106 
     | 
    
         
             
            - ".rspec"
         
     | 
| 
       106 
107 
     | 
    
         
             
            - ".rubocop.yml"
         
     | 
| 
         @@ -115,13 +116,13 @@ files: 
     | 
|
| 
       115 
116 
     | 
    
         
             
            - bin/console
         
     | 
| 
       116 
117 
     | 
    
         
             
            - govuk_schemas.gemspec
         
     | 
| 
       117 
118 
     | 
    
         
             
            - lib/govuk_schemas.rb
         
     | 
| 
      
 119 
     | 
    
         
            +
            - lib/govuk_schemas/document_types.rb
         
     | 
| 
       118 
120 
     | 
    
         
             
            - lib/govuk_schemas/example.rb
         
     | 
| 
       119 
     | 
    
         
            -
            - lib/govuk_schemas/ 
     | 
| 
      
 121 
     | 
    
         
            +
            - lib/govuk_schemas/random_content_generator.rb
         
     | 
| 
       120 
122 
     | 
    
         
             
            - lib/govuk_schemas/random_example.rb
         
     | 
| 
       121 
     | 
    
         
            -
            - lib/govuk_schemas/ 
     | 
| 
      
 123 
     | 
    
         
            +
            - lib/govuk_schemas/random_schema_generator.rb
         
     | 
| 
       122 
124 
     | 
    
         
             
            - lib/govuk_schemas/rspec_matchers.rb
         
     | 
| 
       123 
125 
     | 
    
         
             
            - lib/govuk_schemas/schema.rb
         
     | 
| 
       124 
     | 
    
         
            -
            - lib/govuk_schemas/utils.rb
         
     | 
| 
       125 
126 
     | 
    
         
             
            - lib/govuk_schemas/version.rb
         
     | 
| 
       126 
127 
     | 
    
         
             
            homepage: https://github.com/alphagov/govuk_schemas_gem
         
     | 
| 
       127 
128 
     | 
    
         
             
            licenses:
         
     | 
| 
         @@ -135,15 +136,14 @@ required_ruby_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       135 
136 
     | 
    
         
             
              requirements:
         
     | 
| 
       136 
137 
     | 
    
         
             
              - - ">="
         
     | 
| 
       137 
138 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       138 
     | 
    
         
            -
                  version: 2. 
     | 
| 
      
 139 
     | 
    
         
            +
                  version: '2.6'
         
     | 
| 
       139 
140 
     | 
    
         
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
       140 
141 
     | 
    
         
             
              requirements:
         
     | 
| 
       141 
142 
     | 
    
         
             
              - - ">="
         
     | 
| 
       142 
143 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       143 
144 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       144 
145 
     | 
    
         
             
            requirements: []
         
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
            rubygems_version: 2.5.1
         
     | 
| 
      
 146 
     | 
    
         
            +
            rubygems_version: 3.0.3
         
     | 
| 
       147 
147 
     | 
    
         
             
            signing_key: 
         
     | 
| 
       148 
148 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       149 
149 
     | 
    
         
             
            summary: Gem to generate test data based on GOV.UK content schemas
         
     | 
    
        data/lib/govuk_schemas/random.rb
    DELETED
    
    | 
         @@ -1,101 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'securerandom'
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            module GovukSchemas
         
     | 
| 
       4 
     | 
    
         
            -
              # @private
         
     | 
| 
       5 
     | 
    
         
            -
              module Random
         
     | 
| 
       6 
     | 
    
         
            -
                class << self
         
     | 
| 
       7 
     | 
    
         
            -
                  WORDS = %w[Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut suscipit at mauris non bibendum. Ut ac massa est. Aenean tempor imperdiet leo vel interdum. Nam sagittis cursus sem ultricies scelerisque. Quisque porttitor risus vel risus finibus, eu sollicitudin nisl aliquet. Sed sed lectus ac dolor molestie interdum. Nam molestie pellentesque purus ac vestibulum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse non tempor eros. Mauris eu orci hendrerit, volutpat lorem in, tristique libero. Duis a nibh nibh.].freeze
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
                  def string_for_type(type)
         
     | 
| 
       10 
     | 
    
         
            -
                    if type == 'date-time'
         
     | 
| 
       11 
     | 
    
         
            -
                      time
         
     | 
| 
       12 
     | 
    
         
            -
                    elsif type == 'uri'
         
     | 
| 
       13 
     | 
    
         
            -
                      uri
         
     | 
| 
       14 
     | 
    
         
            -
                    else
         
     | 
| 
       15 
     | 
    
         
            -
                      raise "Unknown attribute type `#{type}`"
         
     | 
| 
       16 
     | 
    
         
            -
                    end
         
     | 
| 
       17 
     | 
    
         
            -
                  end
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
                  def time
         
     | 
| 
       20 
     | 
    
         
            -
                    seconds_ago = rand(10_000_000) - 5_000_000
         
     | 
| 
       21 
     | 
    
         
            -
                    (Time.now + seconds_ago).iso8601
         
     | 
| 
       22 
     | 
    
         
            -
                  end
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
                  # TODO: make this more random with query string, optional anchor.
         
     | 
| 
       25 
     | 
    
         
            -
                  def uri
         
     | 
| 
       26 
     | 
    
         
            -
                    "http://example.com#{base_path}#{anchor}"
         
     | 
| 
       27 
     | 
    
         
            -
                  end
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
                  def base_path
         
     | 
| 
       30 
     | 
    
         
            -
                    "/" + rand(1..5).times.map { SecureRandom.uuid }.join('/')
         
     | 
| 
       31 
     | 
    
         
            -
                  end
         
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
                  def govuk_subdomain_url
         
     | 
| 
       34 
     | 
    
         
            -
                    subdomain = rand(2..4).times.map {
         
     | 
| 
       35 
     | 
    
         
            -
                      ('a'..'z').to_a.sample(rand(3..8)).join
         
     | 
| 
       36 
     | 
    
         
            -
                    }.join('.')
         
     | 
| 
       37 
     | 
    
         
            -
                    "https://#{subdomain}.gov.uk#{base_path}"
         
     | 
| 
       38 
     | 
    
         
            -
                  end
         
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
                  def string(minimum_chars = nil, maximum_chars = nil)
         
     | 
| 
       41 
     | 
    
         
            -
                    minimum_chars = minimum_chars || 0
         
     | 
| 
       42 
     | 
    
         
            -
                    maximum_chars = maximum_chars || 100
         
     | 
| 
       43 
     | 
    
         
            -
                    WORDS.sample(rand(minimum_chars..maximum_chars)).join(' ')
         
     | 
| 
       44 
     | 
    
         
            -
                  end
         
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
                  def bool
         
     | 
| 
       47 
     | 
    
         
            -
                    rand(2) == 1
         
     | 
| 
       48 
     | 
    
         
            -
                  end
         
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
                  def anchor
         
     | 
| 
       51 
     | 
    
         
            -
                    "##{SecureRandom.hex}"
         
     | 
| 
       52 
     | 
    
         
            -
                  end
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
                  def random_identifier(separator:)
         
     | 
| 
       55 
     | 
    
         
            -
                    Utils.parameterize(WORDS.sample(rand(1..10)).join('-')).gsub('-', separator)
         
     | 
| 
       56 
     | 
    
         
            -
                  end
         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
                  def string_for_regex(pattern)
         
     | 
| 
       59 
     | 
    
         
            -
                    case pattern.to_s
         
     | 
| 
       60 
     | 
    
         
            -
                    when '^(placeholder|placeholder_.+)$'
         
     | 
| 
       61 
     | 
    
         
            -
                      ['placeholder', "placeholder_#{WORDS.sample}"].sample
         
     | 
| 
       62 
     | 
    
         
            -
                    when '^[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$'
         
     | 
| 
       63 
     | 
    
         
            -
                      SecureRandom.uuid
         
     | 
| 
       64 
     | 
    
         
            -
                    when "^/(([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})+(/([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})*)*)?$"
         
     | 
| 
       65 
     | 
    
         
            -
                      base_path
         
     | 
| 
       66 
     | 
    
         
            -
                    when "^[1-9][0-9]{3}[-/](0[1-9]|1[0-2])[-/](0[1-9]|[12][0-9]|3[0-1])$"
         
     | 
| 
       67 
     | 
    
         
            -
                      Date.today.iso8601
         
     | 
| 
       68 
     | 
    
         
            -
                    when "^[1-9][0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[0-1])$"
         
     | 
| 
       69 
     | 
    
         
            -
                      Date.today.iso8601
         
     | 
| 
       70 
     | 
    
         
            -
                    when "^#.+$"
         
     | 
| 
       71 
     | 
    
         
            -
                      anchor
         
     | 
| 
       72 
     | 
    
         
            -
                    when "[a-z-]"
         
     | 
| 
       73 
     | 
    
         
            -
                      random_identifier(separator: '-')
         
     | 
| 
       74 
     | 
    
         
            -
                    when "^[a-z_]+$"
         
     | 
| 
       75 
     | 
    
         
            -
                      random_identifier(separator: '_')
         
     | 
| 
       76 
     | 
    
         
            -
                    when "^/(([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})+(/([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})*)*)?(\\?([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})*)?(#([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})*)?$"
         
     | 
| 
       77 
     | 
    
         
            -
                      base_path
         
     | 
| 
       78 
     | 
    
         
            -
                    when "^https://([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[A-Za-z0-9])?\\.)+campaign\\.gov\\.uk(/(([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})+(/([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})*)*)?(\\?([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})*)?(#([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})*)?)?$"
         
     | 
| 
       79 
     | 
    
         
            -
                      govuk_subdomain_url
         
     | 
| 
       80 
     | 
    
         
            -
                    when "^https://([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[A-Za-z0-9])?\\.)*gov\\.uk(/(([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})+(/([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})*)*)?(\\?([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})*)?(#([a-zA-Z0-9._~!$&'()*+,;=:@-]|%[0-9a-fA-F]{2})*)?)?$"
         
     | 
| 
       81 
     | 
    
         
            -
                      govuk_subdomain_url
         
     | 
| 
       82 
     | 
    
         
            -
                    when '[a-z0-9\-_]'
         
     | 
| 
       83 
     | 
    
         
            -
                      "#{SecureRandom.hex}-#{SecureRandom.hex}"
         
     | 
| 
       84 
     | 
    
         
            -
                    else
         
     | 
| 
       85 
     | 
    
         
            -
                      raise <<-doc
         
     | 
| 
       86 
     | 
    
         
            -
                        Don't know how to generate random string for pattern #{pattern.inspect}
         
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
       88 
     | 
    
         
            -
                        This propably means you've introduced a new regex in  govuk-content-schemas.
         
     | 
| 
       89 
     | 
    
         
            -
                        Because it's very hard to generate a valid string from a regex alone,
         
     | 
| 
       90 
     | 
    
         
            -
                        we have to specify a method to generate random data for each regex in
         
     | 
| 
       91 
     | 
    
         
            -
                        the schemas.
         
     | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
       93 
     | 
    
         
            -
                        To fix this:
         
     | 
| 
       94 
     | 
    
         
            -
             
     | 
| 
       95 
     | 
    
         
            -
                        - Add your regex to `lib/govuk_schemas/random.rb`
         
     | 
| 
       96 
     | 
    
         
            -
                      doc
         
     | 
| 
       97 
     | 
    
         
            -
                    end
         
     | 
| 
       98 
     | 
    
         
            -
                  end
         
     | 
| 
       99 
     | 
    
         
            -
                end
         
     | 
| 
       100 
     | 
    
         
            -
              end
         
     | 
| 
       101 
     | 
    
         
            -
            end
         
     | 
    
        data/lib/govuk_schemas/utils.rb
    DELETED
    
    | 
         @@ -1,16 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            module GovukSchemas
         
     | 
| 
       2 
     | 
    
         
            -
              # @private
         
     | 
| 
       3 
     | 
    
         
            -
              module Utils
         
     | 
| 
       4 
     | 
    
         
            -
                def self.stringify_keys(hash)
         
     | 
| 
       5 
     | 
    
         
            -
                  new_hash = {}
         
     | 
| 
       6 
     | 
    
         
            -
                  hash.each do |k, v|
         
     | 
| 
       7 
     | 
    
         
            -
                    new_hash[k.to_s] = v
         
     | 
| 
       8 
     | 
    
         
            -
                  end
         
     | 
| 
       9 
     | 
    
         
            -
                  new_hash
         
     | 
| 
       10 
     | 
    
         
            -
                end
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
                def self.parameterize(string)
         
     | 
| 
       13 
     | 
    
         
            -
                  string.gsub(/[^a-z0-9\-_]+/i, '-')
         
     | 
| 
       14 
     | 
    
         
            -
                end
         
     | 
| 
       15 
     | 
    
         
            -
              end
         
     | 
| 
       16 
     | 
    
         
            -
            end
         
     |