pgtk 0.30.5 → 0.30.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5007602ed1eb8c77a95905969c85974f1f89250469008aa6cd92bf52d070a60e
4
- data.tar.gz: e50a291add3ea16c4a3ac6cedb223ae0247e262adba559b7edea39f788708ccc
3
+ metadata.gz: af5dbb83c87c7ade9b9ec80e1c5d63d6c079e3e6d75963c9b20ba3306d151c2d
4
+ data.tar.gz: 9dfb51f191636813b50a067b484b44d1bbcfd28a810e437d6ac4e3539d2b208f
5
5
  SHA512:
6
- metadata.gz: d2345f24e3fe662dc6d1f9fca7fc01505b9ab892cbfe8bb527ac8b743f34bdfac28bd0568a3b41d1ec869796fbec24987f9bf17245c99db30f140abad53514a0
7
- data.tar.gz: eb61998f1a3af79cb76a6adb1d88bf88a525660c1681e7871c083d0ddbaf60e2d0e9eda42e34bc9cff80c9ab141a7831919eda04a2808e82a886f447cdaced94
6
+ metadata.gz: a47bb2c8234ff77dfc0dead336bc0010be2bc2e356fd10df8b37e103b9fa72484558ebe4db1e2e389c9186608bd6362690eb5e78ff354df2fe154a778318052c
7
+ data.tar.gz: '08edebfc99f2225668a613ccec7f79773e1969edd73d69cf7b22ef47838c157164380488f73b90274f86834069b7f3da2fb6abf9ac3dd4e5d50a0bc0786ad1b9'
data/Gemfile CHANGED
@@ -15,6 +15,7 @@ gem 'qbash', '~>0.0', require: false
15
15
  gem 'rack', '~>3.2', require: false
16
16
  gem 'rake', '~>13.2', require: false
17
17
  gem 'rubocop', '~>1.73', require: false
18
+ gem 'rubocop-elegant', '~>0.0', require: false
18
19
  gem 'rubocop-minitest', '~>0.38', require: false
19
20
  gem 'rubocop-performance', '~>1.25', require: false
20
21
  gem 'rubocop-rake', '~>0.7', require: false
data/Gemfile.lock CHANGED
@@ -35,7 +35,7 @@ GEM
35
35
  tago (~> 0.1)
36
36
  ellipsized (0.3.0)
37
37
  joined (0.4.0)
38
- json (2.19.2)
38
+ json (2.19.3)
39
39
  language_server-protocol (3.17.0.5)
40
40
  lint_roller (1.1.0)
41
41
  logger (1.7.0)
@@ -52,15 +52,15 @@ GEM
52
52
  minitest (>= 5.0, < 7)
53
53
  ruby-progressbar
54
54
  minitest-stub-const (0.6)
55
- nokogiri (1.19.1-arm64-darwin)
55
+ nokogiri (1.19.2-arm64-darwin)
56
56
  racc (~> 1.4)
57
- nokogiri (1.19.1-x64-mingw-ucrt)
57
+ nokogiri (1.19.2-x64-mingw-ucrt)
58
58
  racc (~> 1.4)
59
- nokogiri (1.19.1-x86_64-linux-gnu)
59
+ nokogiri (1.19.2-x86_64-linux-gnu)
60
60
  racc (~> 1.4)
61
61
  os (1.1.4)
62
- parallel (1.27.0)
63
- parser (3.3.10.1)
62
+ parallel (2.0.1)
63
+ parser (3.3.11.1)
64
64
  ast (~> 2.4.1)
65
65
  racc
66
66
  pg (1.6.3-arm64-darwin)
@@ -76,25 +76,28 @@ GEM
76
76
  rack (3.2.6)
77
77
  rainbow (3.1.1)
78
78
  rake (13.3.1)
79
- random-port (0.7.6)
79
+ random-port (0.8.2)
80
80
  tago (~> 0.0)
81
- regexp_parser (2.11.3)
81
+ regexp_parser (2.12.0)
82
82
  rexml (3.4.4)
83
- rubocop (1.84.1)
83
+ rubocop (1.86.1)
84
84
  json (~> 2.3)
85
85
  language_server-protocol (~> 3.17.0.2)
86
86
  lint_roller (~> 1.1.0)
87
- parallel (~> 1.10)
87
+ parallel (>= 1.10)
88
88
  parser (>= 3.3.0.2)
89
89
  rainbow (>= 2.2.2, < 4.0)
90
90
  regexp_parser (>= 2.9.3, < 3.0)
91
91
  rubocop-ast (>= 1.49.0, < 2.0)
92
92
  ruby-progressbar (~> 1.7)
93
93
  unicode-display_width (>= 2.4.0, < 4.0)
94
- rubocop-ast (1.49.0)
94
+ rubocop-ast (1.49.1)
95
95
  parser (>= 3.3.7.2)
96
96
  prism (~> 1.7)
97
- rubocop-minitest (0.38.2)
97
+ rubocop-elegant (0.0.14)
98
+ lint_roller (~> 1.1)
99
+ rubocop (~> 1.75)
100
+ rubocop-minitest (0.39.1)
98
101
  lint_roller (~> 1.1)
99
102
  rubocop (>= 1.75.0, < 2.0)
100
103
  rubocop-ast (>= 1.38.0, < 2.0)
@@ -130,7 +133,7 @@ GEM
130
133
  nokogiri (~> 1.10)
131
134
  rainbow (~> 3.0)
132
135
  slop (~> 4.4)
133
- yard (0.9.38)
136
+ yard (0.9.39)
134
137
 
135
138
  PLATFORMS
136
139
  arm64-darwin-22
@@ -150,6 +153,7 @@ DEPENDENCIES
150
153
  rack (~> 3.2)
151
154
  rake (~> 13.2)
152
155
  rubocop (~> 1.73)
156
+ rubocop-elegant (~> 0.0)
153
157
  rubocop-minitest (~> 0.38)
154
158
  rubocop-performance (~> 1.25)
155
159
  rubocop-rake (~> 0.7)
data/Rakefile CHANGED
@@ -5,9 +5,9 @@
5
5
 
6
6
  require 'os'
7
7
  require 'qbash'
8
- require 'rubygems'
9
8
  require 'rake'
10
9
  require 'rake/clean'
10
+ require 'rubygems'
11
11
 
12
12
  def name
13
13
  @name ||= File.basename(Dir['*.gemspec'].first, '.*')
@@ -53,7 +53,7 @@ end
53
53
 
54
54
  require 'xcop/rake_task'
55
55
  desc 'Validate all XML/XSL/XSD/HTML files for formatting'
56
- Xcop::RakeTask.new :xcop do |task|
56
+ Xcop::RakeTask.new(:xcop) do |task|
57
57
  task.includes = ['**/*.xml', '**/*.xsl', '**/*.xsd', '**/*.html']
58
58
  task.excludes = ['target/**/*', 'coverage/**/*', 'vendor/**/*', 'doc/**/*']
59
59
  end
@@ -107,15 +107,15 @@ class Pgtk::Impatient
107
107
  @pool.exec(sql, *args)
108
108
  end
109
109
  rescue Timeout::Error => e
110
- raise e unless e.message == token
111
- raise TooSlow, [
110
+ raise(e) unless e.message == token
111
+ raise(TooSlow, [
112
112
  'SQL query',
113
113
  ("with #{args.count} argument#{'s' if args.count > 1}" unless args.empty?),
114
114
  'was terminated after',
115
115
  start.ago,
116
116
  'of waiting:',
117
117
  sql.ellipsized(50).inspect
118
- ].compact.join(' ')
118
+ ].compact.join(' '))
119
119
  end
120
120
  end
121
121
 
@@ -125,8 +125,8 @@ class Pgtk::Impatient
125
125
  # @return [Object] Result of the block
126
126
  def transaction
127
127
  @pool.transaction do |t|
128
- t.exec("SET LOCAL statement_timeout = #{(@timeout * 1000).to_i}")
129
- yield Pgtk::Impatient.new(t, @timeout)
128
+ t.exec("SET LOCAL statement_timeout = #{Integer((@timeout * 1000).to_s, 10)}")
129
+ yield(Pgtk::Impatient.new(t, @timeout))
130
130
  end
131
131
  end
132
132
  end
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'English'
3
4
  # SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
4
5
  # SPDX-License-Identifier: MIT
5
6
 
6
7
  require 'donce'
7
- require 'English'
8
8
  require 'loog'
9
9
  require 'os'
10
10
  require 'qbash'
@@ -19,41 +19,7 @@ require_relative '../pgtk'
19
19
  # Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
20
20
  # License:: MIT
21
21
  class Pgtk::LiquibaseTask < Rake::TaskLib
22
- # Task name
23
- # @return [Symbol]
24
- attr_accessor :name
25
-
26
- # Path to Liquibase master XML file
27
- # @return [String]
28
- attr_accessor :master
29
-
30
- # Path to YAML file with PostgreSQL connection details
31
- # @return [String, Array<String>]
32
- attr_accessor :yaml
33
-
34
- # Path to PG entire SQL schema file, which will be dumped and overwritten after all migrations
35
- # @return [String]
36
- attr_accessor :schema
37
-
38
- # Whether to suppress output
39
- # @return [Boolean]
40
- attr_accessor :quiet
41
-
42
- # Liquibase version to use
43
- # @return [String]
44
- attr_accessor :liquibase_version
45
-
46
- # PostgreSQL JDBC driver version to use
47
- # @return [String]
48
- attr_accessor :postgresql_version
49
-
50
- # Liquibase contexts to apply
51
- # @return [String]
52
- attr_accessor :contexts
53
-
54
- # Use docker (set to either :never, :always, or :maybe)
55
- # @return [Symbol]
56
- attr_accessor :docker
22
+ attr_accessor :name, :master, :yaml, :schema, :quiet, :liquibase, :postgresql, :contexts, :docker
57
23
 
58
24
  # Initialize a new Liquibase task.
59
25
  #
@@ -65,11 +31,11 @@ class Pgtk::LiquibaseTask < Rake::TaskLib
65
31
  @name = args.shift || :liquibase
66
32
  @quiet = false
67
33
  @contexts = ''
68
- @liquibase_version = '3.2.2'
69
- @postgresql_version = '42.7.0'
70
- desc 'Deploy Liquibase changes to the running PostgreSQL server' unless ::Rake.application.last_description
34
+ @liquibase = '3.2.2'
35
+ @postgresql = '42.7.0'
36
+ desc('Deploy Liquibase changes to the running PostgreSQL server') unless ::Rake.application.last_description
71
37
  task(name, *args) do |_, task_args|
72
- RakeFileUtils.send(:verbose, true) do
38
+ RakeFileUtils.verbose(true) do
73
39
  yield(*[self, task_args].slice(0, task_block.arity)) if block_given?
74
40
  run
75
41
  end
@@ -79,34 +45,48 @@ class Pgtk::LiquibaseTask < Rake::TaskLib
79
45
  private
80
46
 
81
47
  def run
82
- raise "Option 'master' is mandatory" unless @master
83
- raise "Option 'yaml' is mandatory" unless @yaml
84
- yml = @yaml
85
- unless yml.is_a?(Hash)
86
- yml = YAML.load_file(
87
- if @yaml.is_a?(Array)
88
- @yaml.drop_while { |f| !File.exist?(f) }.first
89
- else
90
- @yaml
91
- end
92
- )
93
- end
94
- raise "YAML configuration is missing the 'pgsql' section" unless yml['pgsql']
48
+ raise(ArgumentError, "Option 'master' is mandatory") unless @master
49
+ raise(ArgumentError, "Option 'yaml' is mandatory") unless @yaml
50
+ yml = config
95
51
  @master = File.expand_path(@master)
52
+ validate(yml)
53
+ migrate(yml)
54
+ dump(yml) if @schema
55
+ end
56
+
57
+ def config
58
+ yml = @yaml
59
+ return yml if yml.is_a?(Hash)
60
+ YAML.load_file(
61
+ if @yaml.is_a?(Array)
62
+ @yaml.drop_while { |f| !File.exist?(f) }.first
63
+ else
64
+ @yaml
65
+ end
66
+ )
67
+ end
68
+
69
+ def validate(yml)
70
+ raise(ArgumentError, "YAML configuration is missing the 'pgsql' section") unless yml['pgsql']
96
71
  unless File.exist?(@master)
97
- raise \
72
+ raise(
73
+ ArgumentError,
98
74
  "Liquibase master is absent at '#{@master}'. " \
99
75
  'More about this file you can find in Liquibase documentation: ' \
100
76
  'https://docs.liquibase.com/concepts/changelogs/xml-format.html'
77
+ )
101
78
  end
79
+ raise(ArgumentError, "The 'url' is not set in the config (YAML)") if yml['pgsql']['url'].nil?
80
+ raise(ArgumentError, "The 'user' is not set in the config (YAML)") if yml['pgsql']['user'].nil?
81
+ raise(ArgumentError, "The 'password' is not set in the config (YAML)") if yml['pgsql']['password'].nil?
82
+ end
83
+
84
+ def migrate(yml)
102
85
  pom = File.expand_path(File.join(__dir__, '../../resources/pom.xml'))
103
- old = @liquibase_version.match?(/^[1-3]\..+$/)
86
+ old = @liquibase.match?(/^[1-3]\..+$/)
104
87
  url = yml['pgsql']['url']
105
- raise "The 'url' is not set in the config (YAML)" if url.nil?
106
88
  username = yml['pgsql']['user']
107
- raise "The 'user' is not set in the config (YAML)" if username.nil?
108
89
  password = yml['pgsql']['password']
109
- raise "The 'password' is not set in the config (YAML)" if password.nil?
110
90
  Dir.chdir(File.dirname(@master)) do
111
91
  qbash(
112
92
  'mvn', 'verify',
@@ -117,9 +97,9 @@ class Pgtk::LiquibaseTask < Rake::TaskLib
117
97
  '--file',
118
98
  Shellwords.escape(pom),
119
99
  '--define',
120
- "liquibase.version=#{@liquibase_version}",
100
+ "liquibase.version=#{@liquibase}",
121
101
  '--define',
122
- "postgresql.version=#{@postgresql_version}",
102
+ "postgresql.version=#{@postgresql}",
123
103
  '--define',
124
104
  Shellwords.escape("liquibase.searchPath=#{File.dirname(@master)}"),
125
105
  '--define',
@@ -136,49 +116,59 @@ class Pgtk::LiquibaseTask < Rake::TaskLib
136
116
  stderr: Loog::REGULAR
137
117
  )
138
118
  end
139
- return unless @schema
119
+ end
120
+
121
+ def dump(yml)
140
122
  @schema = File.expand_path(@schema)
141
- dump = qbash('pg_dump -V', accept: nil, both: true)
142
- local = dump[1].zero?
123
+ local = qbash('pg_dump -V', accept: nil, both: true)[1].zero?
143
124
  docker = qbash('docker -v', accept: nil, both: true)[1].zero?
144
- raise 'Cannot generate schema, install either pg_dump or Docker' unless local || docker
145
- raise 'You set docker to :always, but Docker is not installed' if @docker == :always && !docker
125
+ raise(IOError, 'Cannot generate schema, install either pg_dump or Docker') unless local || docker
126
+ raise(ArgumentError, 'You set docker to :always, but Docker is not installed') if @docker == :always && !docker
127
+ password = yml['pgsql']['password']
146
128
  host = yml.dig('pgsql', 'host')
147
129
  Dir.chdir(File.dirname(@schema)) do
148
130
  out =
149
131
  if (local && @docker != :always) || @docker == :never
150
- qbash(
151
- 'pg_dump',
152
- '-h', Shellwords.escape(host),
153
- '-p', Shellwords.escape(yml.dig('pgsql', 'port').to_s),
154
- '-U', Shellwords.escape(yml.dig('pgsql', 'user')),
155
- '-d', Shellwords.escape(yml.dig('pgsql', 'dbname')),
156
- '-n', 'public',
157
- '--schema-only',
158
- env: { 'PGPASSWORD' => password },
159
- stdout: @quiet ? Loog::NULL : Loog::REGULAR,
160
- stderr: Loog::REGULAR
161
- )
132
+ pgdump(yml, host, password)
162
133
  else
163
134
  host = donce_host if OS.mac? && ['localhost', '127.0.0.1'].include?(host)
164
- donce(
165
- image: 'postgres:18.1',
166
- args: OS.mac? ? '' : '--network=host',
167
- env: { 'PGPASSWORD' => password },
168
- command: [
169
- 'pg_dump',
170
- '-h', host,
171
- '-p', yml.dig('pgsql', 'port').to_s,
172
- '-U', yml.dig('pgsql', 'user'),
173
- '-d', yml.dig('pgsql', 'dbname'),
174
- '-n', 'public',
175
- '--schema-only'
176
- ].shelljoin,
177
- stdout: @quiet ? Loog::NULL : Loog::REGULAR,
178
- stderr: Loog::REGULAR
179
- )
135
+ dockerdump(yml, host, password)
180
136
  end
181
137
  File.write(@schema, out)
182
138
  end
183
139
  end
140
+
141
+ def pgdump(yml, host, password)
142
+ qbash(
143
+ 'pg_dump',
144
+ '-h', Shellwords.escape(host),
145
+ '-p', Shellwords.escape(yml.dig('pgsql', 'port').to_s),
146
+ '-U', Shellwords.escape(yml.dig('pgsql', 'user')),
147
+ '-d', Shellwords.escape(yml.dig('pgsql', 'dbname')),
148
+ '-n', 'public',
149
+ '--schema-only',
150
+ env: { 'PGPASSWORD' => password },
151
+ stdout: @quiet ? Loog::NULL : Loog::REGULAR,
152
+ stderr: Loog::REGULAR
153
+ )
154
+ end
155
+
156
+ def dockerdump(yml, host, password)
157
+ donce(
158
+ image: 'postgres:18.1',
159
+ args: OS.mac? ? '' : '--network=host',
160
+ env: { 'PGPASSWORD' => password },
161
+ command: [
162
+ 'pg_dump',
163
+ '-h', host,
164
+ '-p', yml.dig('pgsql', 'port').to_s,
165
+ '-U', yml.dig('pgsql', 'user'),
166
+ '-d', yml.dig('pgsql', 'dbname'),
167
+ '-n', 'public',
168
+ '--schema-only'
169
+ ].shelljoin,
170
+ stdout: @quiet ? Loog::NULL : Loog::REGULAR,
171
+ stderr: Loog::REGULAR
172
+ )
173
+ end
184
174
  end
@@ -12,26 +12,16 @@ require_relative '../pgtk'
12
12
  # Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
13
13
  # License:: MIT
14
14
  class Pgtk::LiquicheckTask < Rake::TaskLib
15
- # Task name
16
- # @return [Symbol]
17
- attr_accessor :name
18
-
19
- # Base directory where Liquibase XML files will be stored
20
- # @return [String]
21
- attr_accessor :dir
22
-
23
- # Migration XML files pattern
24
- # @return [String]
25
- attr_accessor :pattern
15
+ attr_accessor :name, :dir, :pattern
26
16
 
27
17
  def initialize(*args, &task_block)
28
18
  super()
29
19
  @name = args.shift || :liquicheck
30
20
  @dir = 'liquibase'
31
21
  @pattern = '*/*.xml'
32
- desc 'Check the quality of Liquibase XML files' unless ::Rake.application.last_description
22
+ desc('Check the quality of Liquibase XML files') unless ::Rake.application.last_description
33
23
  task(name, *args) do |_, task_args|
34
- RakeFileUtils.send(:verbose, true) do
24
+ RakeFileUtils.verbose(true) do
35
25
  yield(*[self, task_args].slice(0, task_block.arity)) if block_given?
36
26
  run
37
27
  end
@@ -41,54 +31,62 @@ class Pgtk::LiquicheckTask < Rake::TaskLib
41
31
  private
42
32
 
43
33
  def run
44
- raise "Option 'dir' is mandatory" if !@dir || @dir.empty?
45
- raise "Option 'pattern' is mandatory" if !@pattern || @pattern.empty?
34
+ raise(ArgumentError, "Option 'dir' is mandatory") if !@dir || @dir.empty?
35
+ raise(ArgumentError, "Option 'pattern' is mandatory") if !@pattern || @pattern.empty?
46
36
  errors = {}
47
37
  Dir[File.join(File.expand_path(File.join(Dir.pwd, @dir)), @pattern)].each do |file|
48
- doc = Nokogiri::XML(File.open(file))
49
- doc.remove_namespaces!
50
- path = doc.at_xpath('databaseChangeLog')&.attr('logicalFilePath')&.to_s
51
- on(errors, file) do
52
- must_have(path, 'logicalFilePath is empty')
53
- must_equal(
54
- path,
55
- File.basename(file),
56
- "logicalFilePath #{path.inspect} does not equal the xml file name #{File.basename(file).inspect}"
57
- )
58
- end
59
- doc.xpath('databaseChangeLog/changeSet').each do |node|
60
- id = node.attr('id')&.to_s
61
- author = node.attr('author')&.to_s
62
- context = node.attr('context')&.to_s
63
- on(errors, file) do
64
- must_have(id, 'ID is empty')
65
- must_match(id, /[-a-z]+/, "ID #{id.inspect} has not suffix in #{context} context") if context
66
- end
67
- on(errors, file) do
68
- must_have(author, 'author is empty')
69
- must_match(
70
- author,
71
- /\A[-_ A-Za-z0-9]+\z/,
72
- "author #{author.inspect} has illegal symbols"
73
- )
74
- end
75
- on(errors, file) do
76
- must_have(id, 'ID is empty')
77
- must_have(path, 'logicalFilePath is empty')
78
- must_match(
79
- path.gsub(/[-_.a-z]/, ''),
80
- /\A#{id.gsub(/[-a-z]/, '')}\z/,
81
- "ID #{id.inspect} is not the beginning of a logicalFilePath #{path.inspect}"
82
- )
83
- end
84
- end
38
+ inspect(errors, file)
39
+ end
40
+ report(errors)
41
+ end
42
+
43
+ def inspect(errors, file)
44
+ doc = Nokogiri::XML(File.open(file))
45
+ doc.remove_namespaces!
46
+ path = doc.at_xpath('databaseChangeLog')&.attr('logicalFilePath')&.to_s
47
+ on(errors, file) do
48
+ demand(path, 'logicalFilePath is empty')
49
+ equate(
50
+ path,
51
+ File.basename(file),
52
+ "logicalFilePath #{path.inspect} does not equal the xml file name #{File.basename(file).inspect}"
53
+ )
54
+ end
55
+ doc.xpath('databaseChangeLog/changeSet').each do |node|
56
+ verify(errors, file, node, path)
85
57
  end
58
+ end
59
+
60
+ def verify(errors, file, node, path)
61
+ id = node.attr('id')&.to_s
62
+ author = node.attr('author')&.to_s
63
+ context = node.attr('context')&.to_s
64
+ on(errors, file) do
65
+ demand(id, 'ID is empty')
66
+ confirm(id, /[-a-z]+/, "ID #{id.inspect} has not suffix in #{context} context") if context
67
+ end
68
+ on(errors, file) do
69
+ demand(author, 'author is empty')
70
+ confirm(author, /\A[-_ A-Za-z0-9]+\z/, "author #{author.inspect} has illegal symbols")
71
+ end
72
+ on(errors, file) do
73
+ demand(id, 'ID is empty')
74
+ demand(path, 'logicalFilePath is empty')
75
+ confirm(
76
+ path.gsub(/[-_.a-z]/, ''),
77
+ /\A#{id.gsub(/[-a-z]/, '')}\z/,
78
+ "ID #{id.inspect} is not the beginning of a logicalFilePath #{path.inspect}"
79
+ )
80
+ end
81
+ end
82
+
83
+ def report(errors)
86
84
  return if errors.empty?
87
- puts 'There are such errors in the Liquibase XML files.'
85
+ puts('There are such errors in the Liquibase XML files.')
88
86
  errors.each do |f, e|
89
- puts "In file '#{f}':"
87
+ puts("In file '#{f}':")
90
88
  e.uniq.each do |msg|
91
- puts " * #{msg}"
89
+ puts(" * #{msg}")
92
90
  end
93
91
  puts
94
92
  end
@@ -101,20 +99,19 @@ class Pgtk::LiquicheckTask < Rake::TaskLib
101
99
  (errors[file] ||= []) << e.message
102
100
  end
103
101
 
104
- def must_have(prop, msg)
105
- (raise MustError, msg) if prop.nil? || prop.empty?
102
+ def demand(prop, msg)
103
+ raise(MustError, msg) if prop.nil? || prop.empty?
106
104
  end
107
105
 
108
- def must_equal(lprop, rprop, msg)
109
- (raise MustError, msg) if lprop != rprop
106
+ def equate(lprop, rprop, msg)
107
+ raise(MustError, msg) if lprop != rprop
110
108
  end
111
109
 
112
- def must_match(prop, regex, msg)
113
- (raise MustError, msg) unless prop.match?(regex)
110
+ def confirm(prop, regex, msg)
111
+ raise(MustError, msg) unless prop.match?(regex)
114
112
  end
115
113
 
116
114
  class MustError < StandardError
117
- # empty by design
118
115
  end
119
116
  private_constant :MustError
120
117
  end