govuk_schemas 3.1.0 → 4.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 9297a4053527dcb203bec4ff865778ce6f97c542
4
- data.tar.gz: e52f17ca990bb26413119b78dec6e5bf45bc4784
2
+ SHA256:
3
+ metadata.gz: 8123e8bc3461346b31359b47c260930e11505206315aedbfde7532b1601a1e7e
4
+ data.tar.gz: 3ad819db46a04377edda67d60f3a49c08493723a9b40eefd0d72eade6e1b752c
5
5
  SHA512:
6
- metadata.gz: ec518f9fd857d4f05035fa1b22a9bb72bc64e4c40745ca87f28a6e4f09834d1ce1e745d8831bbd1dbe2934a449aa0ad0e21ad7b2cc4f9876e48236310d2efd1e
7
- data.tar.gz: cef56f3ce00f7586d6d80435578325deb0afd89d452f6d5d409be18d10ba1b061fde25a2754386b5ae44d45c5963bd60689159c58013907a87aba98e1bb2d1b2
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
@@ -1,2 +1,6 @@
1
+ inherit_gem:
2
+ rubocop-govuk:
3
+ - config/default.yml
4
+
1
5
  AllCops:
2
- TargetRubyVersion: 2.3
6
+ TargetRubyVersion: 2.6
@@ -1 +1 @@
1
- 2.3.1
1
+ 2.6.6
@@ -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
@@ -1,4 +1,4 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in govuk_schemas.gemspec
4
4
  gemspec
@@ -1,50 +1,9 @@
1
1
  #!/usr/bin/env groovy
2
2
 
3
- REPOSITORY = 'govuk_schemas'
3
+ library("govuk")
4
4
 
5
5
  node {
6
- def govuk = load '/var/lib/jenkins/groovy_scripts/govuk_jenkinslib.groovy'
7
-
8
- try {
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
@@ -12,7 +12,7 @@ gem "govuk_schemas", "~> VERSION"
12
12
 
13
13
  ## Usage
14
14
 
15
- [Read the documentation!](http://www.rubydoc.info/github/alphagov/govuk_schemas)
15
+ [Read the documentation!](http://www.rubydoc.info/gems/govuk_schemas)
16
16
 
17
17
  ## Running the test suite
18
18
 
@@ -1,7 +1,6 @@
1
- # coding: utf-8
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 'govuk_schemas/version'
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 = ["lib"]
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 "govuk-lint", "~> 1.2.1"
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.3.1"
30
+ spec.required_ruby_version = ">= 2.6"
32
31
  end
@@ -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 < Exception
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/random"
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 = RandomItemGenerator.new(schema: schema)
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/random"
1
+ require "govuk_schemas/random_content_generator"
2
2
 
3
3
  module GovukSchemas
4
- # The RandomItemGenerator takes a JSON schema and outputs a random hash that
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 RandomItemGenerator
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['$ref'] == "#/definitions/nested_headers"
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['$ref']
35
- props.merge!(lookup_json_pointer(props['$ref']))
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['type'] || "string"
42
+ type = props["type"] || "string"
41
43
 
42
44
  # Except when it has properties, because it's defintely an object then.
43
- if props['properties']
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['anyOf']
51
- generate_value(props['anyOf'].sample)
52
- elsif props['oneOf']
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['oneOf'].sample)
59
- elsif props['allOf']
60
- props['allOf'].each_with_object({}) do |subschema, hash|
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['enum']
65
- props['enum'].sample
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
- Random.bool
75
+ @generator.bool
74
76
  elsif type == "integer"
75
- min = props['minimum'] || 0
76
- max = props['maximum'] || 10
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
- (subschema['properties'] || {}).each do |attribute_name, attribute_properties|
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
- if subschema['required'].to_a.include?(attribute_name) || subschema['minProperties'] || Random.bool
94
- document[attribute_name] = generate_value(attribute_properties)
95
- end
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['minItems'] || 0
103
- max = props['maxItems'] || 10
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['items'] || {})
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
- Random.string_for_type(props['format'])
129
+ @generator.string_for_type(props["format"])
115
130
  elsif props["pattern"]
116
- Random.string_for_regex(props['pattern'])
131
+ @generator.string_for_regex(props["pattern"])
117
132
  else
118
- Random.string(props['minLength'], props['maxLength'])
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
- RSpec::Matchers.define :be_valid_against_schema do |schema_name|
4
- match do |item|
5
- schema = Schema.find(publisher_schema: schema_name)
6
- validator = JSON::Validator.fully_validate(schema, item)
7
- validator.empty?
8
- end
9
-
10
- failure_message do |actual|
11
- ValidationErrorMessage.new(schema_name, "schema", actual).message
12
- end
13
- end
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
- <<~doc
40
- expected the payload to be valid against the '#{schema_name}' schema:
29
+ <<~DOC
30
+ expected the payload to be valid against the '#{schema_name}' schema:
41
31
 
42
- #{formatted_payload}
32
+ #{formatted_payload}
43
33
 
44
- Validation errors:
45
- #{errors}
46
- doc
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
 
@@ -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").reduce({}) do |hash, file_path|
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
 
@@ -1,4 +1,4 @@
1
1
  module GovukSchemas
2
2
  # @private
3
- VERSION = "3.1.0".freeze
3
+ VERSION = "4.1.1".freeze
4
4
  end
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: 3.1.0
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: 2017-12-11 00:00:00.000000000 Z
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: rake
28
+ name: pry-byebug
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
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: '10.0'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rspec
42
+ name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '3.4'
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: '3.4'
54
+ version: '13.0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: pry-byebug
56
+ name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
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: '0'
68
+ version: '3.4'
69
69
  - !ruby/object:Gem::Dependency
70
- name: govuk-lint
70
+ name: rubocop-govuk
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 1.2.1
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: 1.2.1
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/random.rb
121
+ - lib/govuk_schemas/random_content_generator.rb
120
122
  - lib/govuk_schemas/random_example.rb
121
- - lib/govuk_schemas/random_item_generator.rb
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.3.1
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
- rubyforge_project:
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
@@ -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
@@ -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