minitest 5.14.4 → 5.20.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/minitest/unit.rb CHANGED
@@ -1,5 +1,3 @@
1
- # :stopdoc:
2
-
3
1
  unless defined?(Minitest) then
4
2
  # all of this crap is just to avoid circular requires and is only
5
3
  # needed if a user requires "minitest/unit" directly instead of
@@ -10,17 +8,18 @@ unless defined?(Minitest) then
10
8
  warn %(Warning: or add 'gem "minitest"' before 'require "minitest/autorun"')
11
9
  warn "From:\n #{from}"
12
10
 
13
- module Minitest; end
14
- MiniTest = Minitest # prevents minitest.rb from requiring back to us
11
+ module Minitest # :nodoc:
12
+ end
13
+ MiniTest = Minitest # :nodoc: # prevents minitest.rb from requiring back to us
15
14
  require "minitest"
16
15
  end
17
16
 
18
17
  MiniTest = Minitest unless defined?(MiniTest)
19
18
 
20
19
  module Minitest
21
- class Unit
20
+ class Unit # :nodoc:
22
21
  VERSION = Minitest::VERSION
23
- class TestCase < Minitest::Test
22
+ class TestCase < Minitest::Test # :nodoc:
24
23
  def self.inherited klass # :nodoc:
25
24
  from = caller.first
26
25
  warn "MiniTest::Unit::TestCase is now Minitest::Test. From #{from}"
@@ -41,5 +40,3 @@ module Minitest
41
40
  end
42
41
  end
43
42
  end
44
-
45
- # :startdoc:
data/lib/minitest.rb CHANGED
@@ -3,56 +3,74 @@ require "thread"
3
3
  require "mutex_m"
4
4
  require "minitest/parallel"
5
5
  require "stringio"
6
+ require "etc"
6
7
 
7
8
  ##
8
9
  # :include: README.rdoc
9
10
 
10
11
  module Minitest
11
- VERSION = "5.14.4" # :nodoc:
12
- ENCS = "".respond_to? :encoding # :nodoc:
12
+ VERSION = "5.20.0" # :nodoc:
13
13
 
14
14
  @@installed_at_exit ||= false
15
15
  @@after_run = []
16
16
  @extensions = []
17
17
 
18
- mc = (class << self; self; end)
18
+ def self.cattr_accessor name # :nodoc:
19
+ (class << self; self; end).attr_accessor name
20
+ end
21
+
22
+ ##
23
+ # The random seed used for this run. This is used to srand at the
24
+ # start of the run and between each +Runnable.run+.
25
+ #
26
+ # Set via Minitest.run after processing args.
27
+
28
+ cattr_accessor :seed
19
29
 
20
30
  ##
21
31
  # Parallel test executor
22
32
 
23
- mc.send :attr_accessor, :parallel_executor
33
+ cattr_accessor :parallel_executor
34
+
35
+ warn "DEPRECATED: use MT_CPU instead of N for parallel test runs" if ENV["N"] && ENV["N"].to_i > 0
36
+ n_threads = (ENV["MT_CPU"] || ENV["N"] || Etc.nprocessors).to_i
24
37
 
25
- warn "DEPRECATED: use MT_CPU instead of N for parallel test runs" if ENV["N"]
26
- n_threads = (ENV["MT_CPU"] || ENV["N"] || 2).to_i
27
38
  self.parallel_executor = Parallel::Executor.new n_threads
28
39
 
29
40
  ##
30
41
  # Filter object for backtraces.
31
42
 
32
- mc.send :attr_accessor, :backtrace_filter
43
+ cattr_accessor :backtrace_filter
33
44
 
34
45
  ##
35
46
  # Reporter object to be used for all runs.
36
47
  #
37
48
  # NOTE: This accessor is only available during setup, not during runs.
38
49
 
39
- mc.send :attr_accessor, :reporter
50
+ cattr_accessor :reporter
40
51
 
41
52
  ##
42
53
  # Names of known extension plugins.
43
54
 
44
- mc.send :attr_accessor, :extensions
55
+ cattr_accessor :extensions
45
56
 
46
57
  ##
47
58
  # The signal to use for dumping information to STDERR. Defaults to "INFO".
48
59
 
49
- mc.send :attr_accessor, :info_signal
60
+ cattr_accessor :info_signal
50
61
  self.info_signal = "INFO"
51
62
 
63
+ cattr_accessor :allow_fork
64
+ self.allow_fork = false
65
+
52
66
  ##
53
67
  # Registers Minitest to run at process exit
54
68
 
55
69
  def self.autorun
70
+ if Object.const_defined?(:Warning) && Warning.respond_to?(:[]=)
71
+ Warning[:deprecated] = true
72
+ end
73
+
56
74
  at_exit {
57
75
  next if $! and not ($!.kind_of? SystemExit and $!.success?)
58
76
 
@@ -60,7 +78,7 @@ module Minitest
60
78
 
61
79
  pid = Process.pid
62
80
  at_exit {
63
- next if Process.pid != pid
81
+ next if !Minitest.allow_fork && Process.pid != pid
64
82
  @@after_run.reverse_each(&:call)
65
83
  exit exit_code || false
66
84
  }
@@ -127,6 +145,9 @@ module Minitest
127
145
 
128
146
  options = process_args args
129
147
 
148
+ Minitest.seed = options[:seed]
149
+ srand Minitest.seed
150
+
130
151
  reporter = CompositeReporter.new
131
152
  reporter << SummaryReporter.new(options[:io], options)
132
153
  reporter << ProgressReporter.new(options[:io], options)
@@ -153,7 +174,7 @@ module Minitest
153
174
  # sub-classes to run.
154
175
 
155
176
  def self.__run reporter, options
156
- suites = Runnable.runnables.reject { |s| s.runnable_methods.empty? }.shuffle
177
+ suites = Runnable.runnables.shuffle
157
178
  parallel, serial = suites.partition { |s| s.test_order == :parallel }
158
179
 
159
180
  # If we run the parallel tests before the serial tests, the parallel tests
@@ -191,6 +212,10 @@ module Minitest
191
212
  options[:verbose] = true
192
213
  end
193
214
 
215
+ opts.on "--show-skips", "Show skipped at the end of run." do
216
+ options[:show_skips] = true
217
+ end
218
+
194
219
  opts.on "-n", "--name PATTERN", "Filter run on /regexp/ or string." do |a|
195
220
  options[:filter] = a
196
221
  end
@@ -199,6 +224,10 @@ module Minitest
199
224
  options[:exclude] = a
200
225
  end
201
226
 
227
+ opts.on "-S", "--skip CODES", String, "Skip reporting of certain types of results (eg E)." do |s|
228
+ options[:skip] = s.chars.to_a
229
+ end
230
+
202
231
  unless extensions.empty?
203
232
  opts.separator ""
204
233
  opts.separator "Known extensions: #{extensions.join(", ")}"
@@ -228,8 +257,6 @@ module Minitest
228
257
  orig_args << "--seed" << options[:seed].to_s
229
258
  end
230
259
 
231
- srand options[:seed]
232
-
233
260
  options[:args] = orig_args.map { |s|
234
261
  s =~ /[\s|&<>$()]/ ? s.inspect : s
235
262
  }.join " "
@@ -307,19 +334,25 @@ module Minitest
307
334
  # reporter to record.
308
335
 
309
336
  def self.run reporter, options = {}
310
- filter = options[:filter] || "/./"
311
- filter = Regexp.new $1 if filter.is_a?(String) && filter =~ %r%/(.*)/%
312
-
313
- filtered_methods = self.runnable_methods.find_all { |m|
314
- filter === m || filter === "#{self}##{m}"
315
- }
337
+ filtered_methods = if options[:filter]
338
+ filter = options[:filter]
339
+ filter = Regexp.new $1 if filter.is_a?(String) && filter =~ %r%/(.*)/%
340
+
341
+ self.runnable_methods.find_all { |m|
342
+ filter === m || filter === "#{self}##{m}"
343
+ }
344
+ else
345
+ self.runnable_methods
346
+ end
316
347
 
317
- exclude = options[:exclude]
318
- exclude = Regexp.new $1 if exclude =~ %r%/(.*)/%
348
+ if options[:exclude]
349
+ exclude = options[:exclude]
350
+ exclude = Regexp.new $1 if exclude =~ %r%/(.*)/%
319
351
 
320
- filtered_methods.delete_if { |m|
321
- exclude === m || exclude === "#{self}##{m}"
322
- }
352
+ filtered_methods.delete_if { |m|
353
+ exclude === m || exclude === "#{self}##{m}"
354
+ }
355
+ end
323
356
 
324
357
  return if filtered_methods.empty?
325
358
 
@@ -341,6 +374,14 @@ module Minitest
341
374
  reporter.record Minitest.run_one_method(klass, method_name)
342
375
  end
343
376
 
377
+ ##
378
+ # Defines the order to run tests (:random by default). Override
379
+ # this or use a convenience method to change it for your tests.
380
+
381
+ def self.test_order
382
+ :random
383
+ end
384
+
344
385
  def self.with_info_handler reporter, &block # :nodoc:
345
386
  handler = lambda do
346
387
  unless reporter.passed? then
@@ -408,6 +449,31 @@ module Minitest
408
449
  self.name = name
409
450
  self.failures = []
410
451
  self.assertions = 0
452
+ # lazy initializer for metadata
453
+ end
454
+
455
+ ##
456
+ # Metadata you attach to the test results that get sent to the reporter.
457
+ #
458
+ # Lazily initializes to a hash, to keep memory down.
459
+ #
460
+ # NOTE: this data *must* be plain (read: marshal-able) data!
461
+ # Hashes! Arrays! Strings!
462
+
463
+ def metadata
464
+ @metadata ||= {}
465
+ end
466
+
467
+ ##
468
+ # Sets metadata, mainly used for +Result.from+.
469
+
470
+ attr_writer :metadata
471
+
472
+ ##
473
+ # Returns true if metadata exists.
474
+
475
+ def metadata?
476
+ defined? @metadata
411
477
  end
412
478
 
413
479
  ##
@@ -528,6 +594,7 @@ module Minitest
528
594
  r.assertions = o.assertions
529
595
  r.failures = o.failures.dup
530
596
  r.time = o.time
597
+ r.metadata = o.metadata if o.metadata?
531
598
 
532
599
  r.source_location = o.method(o.name).source_location rescue ["unknown", -1]
533
600
 
@@ -784,9 +851,14 @@ module Minitest
784
851
 
785
852
  def aggregated_results io # :nodoc:
786
853
  filtered_results = results.dup
787
- filtered_results.reject!(&:skipped?) unless options[:verbose]
854
+ filtered_results.reject!(&:skipped?) unless
855
+ options[:verbose] or options[:show_skips]
856
+
857
+ skip = options[:skip] || []
788
858
 
789
859
  filtered_results.each_with_index { |result, i|
860
+ next if skip.include? result.result_code
861
+
790
862
  io.puts "\n%3d) %s" % [i+1, result]
791
863
  }
792
864
  io.puts
@@ -794,26 +866,19 @@ module Minitest
794
866
  end
795
867
 
796
868
  def to_s # :nodoc:
797
- aggregated_results(StringIO.new(binary_string)).string
869
+ aggregated_results(StringIO.new(''.b)).string
798
870
  end
799
871
 
800
872
  def summary # :nodoc:
801
873
  extra = ""
802
874
 
803
875
  extra = "\n\nYou have skipped tests. Run with --verbose for details." if
804
- results.any?(&:skipped?) unless options[:verbose] or ENV["MT_NO_SKIP_MSG"]
876
+ results.any?(&:skipped?) unless
877
+ options[:verbose] or options[:show_skips] or ENV["MT_NO_SKIP_MSG"]
805
878
 
806
879
  "%d runs, %d assertions, %d failures, %d errors, %d skips%s" %
807
880
  [count, assertions, failures, errors, skips, extra]
808
881
  end
809
-
810
- private
811
-
812
- if '<3'.respond_to? :b
813
- def binary_string; ''.b; end
814
- else
815
- def binary_string; ''.force_encoding(Encoding::ASCII_8BIT); end
816
- end
817
882
  end
818
883
 
819
884
  ##
@@ -129,7 +129,7 @@ class MetaMetaMetaTestCase < Minitest::Test
129
129
 
130
130
  def setup
131
131
  super
132
- srand 42
132
+ Minitest.seed = 42
133
133
  Minitest::Test.reset
134
134
  @tu = nil
135
135
  end
@@ -28,6 +28,9 @@ class TestMinitestAssertions < Minitest::Test
28
28
 
29
29
  RUBY18 = !defined? Encoding
30
30
 
31
+ # not included in JRuby
32
+ RE_LEVELS = /\(\d+ levels\) /
33
+
31
34
  class DummyTest
32
35
  include Minitest::Assertions
33
36
  # include Minitest::Reportable # TODO: why do I really need this?
@@ -351,7 +354,7 @@ class TestMinitestAssertions < Minitest::Test
351
354
  @@ -1,3 +1,3 @@
352
355
  -# encoding: UTF-8
353
356
  -# valid: false
354
- +# encoding: ASCII-8BIT
357
+ +# encoding: #{Encoding::BINARY.name}
355
358
  +# valid: true
356
359
  "bad-utf8-\\xF1.txt"
357
360
  EOM
@@ -370,7 +373,7 @@ class TestMinitestAssertions < Minitest::Test
370
373
  @@ -1,3 +1,3 @@
371
374
  -# encoding: US-ASCII
372
375
  -# valid: false
373
- +# encoding: ASCII-8BIT
376
+ +# encoding: #{Encoding::BINARY.name}
374
377
  +# valid: true
375
378
  "bad-utf8-\\xF1.txt"
376
379
  EOM
@@ -481,7 +484,10 @@ class TestMinitestAssertions < Minitest::Test
481
484
 
482
485
  def test_assert_match
483
486
  @assertion_count = 2
484
- @tc.assert_match(/\w+/, "blah blah blah")
487
+ m = @tc.assert_match(/\w+/, "blah blah blah")
488
+
489
+ assert_kind_of MatchData, m
490
+ assert_equal "blah", m[0]
485
491
  end
486
492
 
487
493
  def test_assert_match_matchee_to_str
@@ -756,12 +762,12 @@ class TestMinitestAssertions < Minitest::Test
756
762
  Class: <SomeError>
757
763
  Message: <\"blah\">
758
764
  ---Backtrace---
759
- FILE:LINE:in \`test_assert_raises_default_triggered\'
765
+ FILE:LINE:in \`block in test_assert_raises_default_triggered\'
760
766
  ---------------
761
767
  EOM
762
768
 
763
769
  actual = e.message.gsub(/^.+:\d+/, "FILE:LINE")
764
- actual.gsub!(/block \(\d+ levels\) in /, "") if RUBY_VERSION >= "1.9.0"
770
+ actual.gsub!(RE_LEVELS, "") unless jruby?
765
771
 
766
772
  assert_equal expected, actual
767
773
  end
@@ -801,7 +807,7 @@ class TestMinitestAssertions < Minitest::Test
801
807
  # *sigh* This is quite an odd scenario, but it is from real (albeit
802
808
  # ugly) test code in ruby-core:
803
809
 
804
- # http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=29259
810
+ # https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=29259
805
811
 
806
812
  def test_assert_raises_skip
807
813
  @assertion_count = 0
@@ -835,12 +841,12 @@ class TestMinitestAssertions < Minitest::Test
835
841
  Class: <AnError>
836
842
  Message: <\"some message\">
837
843
  ---Backtrace---
838
- FILE:LINE:in \`test_assert_raises_subclass_triggered\'
844
+ FILE:LINE:in \`block in test_assert_raises_subclass_triggered\'
839
845
  ---------------
840
846
  EOM
841
847
 
842
848
  actual = e.message.gsub(/^.+:\d+/, "FILE:LINE")
843
- actual.gsub!(/block \(\d+ levels\) in /, "") if RUBY_VERSION >= "1.9.0"
849
+ actual.gsub!(RE_LEVELS, "") unless jruby?
844
850
 
845
851
  assert_equal expected.chomp, actual
846
852
  end
@@ -857,12 +863,12 @@ class TestMinitestAssertions < Minitest::Test
857
863
  Class: <SyntaxError>
858
864
  Message: <\"icky\">
859
865
  ---Backtrace---
860
- FILE:LINE:in \`test_assert_raises_triggered_different\'
866
+ FILE:LINE:in \`block in test_assert_raises_triggered_different\'
861
867
  ---------------
862
868
  EOM
863
869
 
864
870
  actual = e.message.gsub(/^.+:\d+/, "FILE:LINE")
865
- actual.gsub!(/block \(\d+ levels\) in /, "") if RUBY_VERSION >= "1.9.0"
871
+ actual.gsub!(RE_LEVELS, "") unless jruby?
866
872
 
867
873
  assert_equal expected, actual
868
874
  end
@@ -880,12 +886,12 @@ class TestMinitestAssertions < Minitest::Test
880
886
  Class: <SyntaxError>
881
887
  Message: <\"icky\">
882
888
  ---Backtrace---
883
- FILE:LINE:in \`test_assert_raises_triggered_different_msg\'
889
+ FILE:LINE:in \`block in test_assert_raises_triggered_different_msg\'
884
890
  ---------------
885
891
  EOM
886
892
 
887
893
  actual = e.message.gsub(/^.+:\d+/, "FILE:LINE")
888
- actual.gsub!(/block \(\d+ levels\) in /, "") if RUBY_VERSION >= "1.9.0"
894
+ actual.gsub!(RE_LEVELS, "") unless jruby?
889
895
 
890
896
  assert_equal expected.chomp, actual
891
897
  end
@@ -995,9 +1001,19 @@ class TestMinitestAssertions < Minitest::Test
995
1001
  end
996
1002
 
997
1003
  def test_assert_throws
998
- @tc.assert_throws :blah do
1004
+ v = @tc.assert_throws :blah do
999
1005
  throw :blah
1000
1006
  end
1007
+
1008
+ assert_nil v
1009
+ end
1010
+
1011
+ def test_assert_throws_value
1012
+ v = @tc.assert_throws :blah do
1013
+ throw :blah, 42
1014
+ end
1015
+
1016
+ assert_equal 42, v
1001
1017
  end
1002
1018
 
1003
1019
  def test_assert_throws_argument_exception
@@ -1046,6 +1062,66 @@ class TestMinitestAssertions < Minitest::Test
1046
1062
  end
1047
1063
  end
1048
1064
 
1065
+ def test_assert_pattern
1066
+ if RUBY_VERSION > "3" then
1067
+ @tc.assert_pattern do
1068
+ exp = if RUBY_VERSION.start_with? "3.0"
1069
+ "(eval):1: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!\n"
1070
+ else
1071
+ ""
1072
+ end
1073
+ assert_output nil, exp do
1074
+ eval "[1,2,3] => [Integer, Integer, Integer]" # eval to escape parser for ruby<3
1075
+ end
1076
+ end
1077
+ else
1078
+ @assertion_count = 0
1079
+
1080
+ assert_raises NotImplementedError do
1081
+ @tc.assert_pattern do
1082
+ # do nothing
1083
+ end
1084
+ end
1085
+ end
1086
+ end
1087
+
1088
+ def test_assert_pattern_traps_nomatchingpatternerror
1089
+ skip unless RUBY_VERSION > "3"
1090
+ exp = if RUBY_VERSION.start_with? "3.0" then
1091
+ "[1, 2, 3]" # terrible error message!
1092
+ else
1093
+ /length mismatch/
1094
+ end
1095
+
1096
+ assert_triggered exp do
1097
+ @tc.assert_pattern do
1098
+ capture_io do # 3.0 is noisy
1099
+ eval "[1,2,3] => [Integer, Integer]" # eval to escape parser for ruby<3
1100
+ end
1101
+ end
1102
+ end
1103
+ end
1104
+
1105
+ def test_assert_pattern_raises_other_exceptions
1106
+ skip unless RUBY_VERSION >= "3.0"
1107
+
1108
+ @assertion_count = 0
1109
+
1110
+ assert_raises RuntimeError do
1111
+ @tc.assert_pattern do
1112
+ raise "boom"
1113
+ end
1114
+ end
1115
+ end
1116
+
1117
+ def test_assert_pattern_with_no_block
1118
+ skip unless RUBY_VERSION >= "3.0"
1119
+
1120
+ assert_triggered "assert_pattern requires a block to capture errors." do
1121
+ @tc.assert_pattern
1122
+ end
1123
+ end
1124
+
1049
1125
  def test_capture_io
1050
1126
  @assertion_count = 0
1051
1127
 
@@ -1298,6 +1374,56 @@ class TestMinitestAssertions < Minitest::Test
1298
1374
  end
1299
1375
  end
1300
1376
 
1377
+ def test_refute_pattern
1378
+ if RUBY_VERSION >= "3.0"
1379
+ @tc.refute_pattern do
1380
+ capture_io do # 3.0 is noisy
1381
+ eval "[1,2,3] => [Integer, Integer, String]"
1382
+ end
1383
+ end
1384
+ else
1385
+ @assertion_count = 0
1386
+
1387
+ assert_raises NotImplementedError do
1388
+ @tc.refute_pattern do
1389
+ eval "[1,2,3] => [Integer, Integer, String]"
1390
+ end
1391
+ end
1392
+ end
1393
+ end
1394
+
1395
+ def test_refute_pattern_expects_nomatchingpatternerror
1396
+ skip unless RUBY_VERSION > "3"
1397
+
1398
+ assert_triggered(/NoMatchingPatternError expected, but nothing was raised./) do
1399
+ @tc.refute_pattern do
1400
+ capture_io do # 3.0 is noisy
1401
+ eval "[1,2,3] => [Integer, Integer, Integer]"
1402
+ end
1403
+ end
1404
+ end
1405
+ end
1406
+
1407
+ def test_refute_pattern_raises_other_exceptions
1408
+ skip unless RUBY_VERSION >= "3.0"
1409
+
1410
+ @assertion_count = 0
1411
+
1412
+ assert_raises RuntimeError do
1413
+ @tc.refute_pattern do
1414
+ raise "boom"
1415
+ end
1416
+ end
1417
+ end
1418
+
1419
+ def test_refute_pattern_with_no_block
1420
+ skip unless RUBY_VERSION >= "3.0"
1421
+
1422
+ assert_triggered "refute_pattern requires a block to capture errors." do
1423
+ @tc.refute_pattern
1424
+ end
1425
+ end
1426
+
1301
1427
  def test_refute_predicate
1302
1428
  @tc.refute_predicate "42", :empty?
1303
1429
  end
@@ -1515,14 +1641,14 @@ class TestMinitestAssertionHelpers < Minitest::Test
1515
1641
 
1516
1642
  def test_mu_pp_for_diff_str_encoding
1517
1643
  str = "A\nB".b
1518
- exp = "# encoding: ASCII-8BIT\n# valid: true\n\"A\nB\""
1644
+ exp = "# encoding: #{Encoding::BINARY.name}\n# valid: true\n\"A\nB\""
1519
1645
 
1520
1646
  assert_mu_pp_for_diff exp, str, :raw
1521
1647
  end
1522
1648
 
1523
1649
  def test_mu_pp_for_diff_str_encoding_both
1524
1650
  str = "A\\n\nB".b
1525
- exp = "# encoding: ASCII-8BIT\n# valid: true\n\"A\\\\n\\nB\""
1651
+ exp = "# encoding: #{Encoding::BINARY.name}\n# valid: true\n\"A\\\\n\\nB\""
1526
1652
 
1527
1653
  assert_mu_pp_for_diff exp, str, :raw
1528
1654
  end
@@ -1562,7 +1688,7 @@ class TestMinitestAssertionHelpers < Minitest::Test
1562
1688
 
1563
1689
  def test_mu_pp_str_encoding
1564
1690
  str = "A\nB".b
1565
- exp = "# encoding: ASCII-8BIT\n# valid: true\n\"A\\nB\""
1691
+ exp = "# encoding: #{Encoding::BINARY.name}\n# valid: true\n\"A\\nB\""
1566
1692
 
1567
1693
  assert_mu_pp exp, str, :raw
1568
1694
  end
@@ -3,7 +3,7 @@ require "minitest/benchmark"
3
3
 
4
4
  ##
5
5
  # Used to verify data:
6
- # http://www.wolframalpha.com/examples/RegressionAnalysis.html
6
+ # https://www.wolframalpha.com/examples/RegressionAnalysis.html
7
7
 
8
8
  class TestMinitestBenchmark < Minitest::Test
9
9
  def test_cls_bench_exp
@@ -110,7 +110,7 @@ class TestMinitestBenchmark < Minitest::Test
110
110
  assert_fit :power, x, y, 0.90, 2.6217, 1.4556
111
111
 
112
112
  # income to % of households below income amount
113
- # http://library.wolfram.com/infocenter/Conferences/6461/PowerLaws.nb
113
+ # https://library.wolfram.com/infocenter/Conferences/6461/PowerLaws.nb
114
114
  x = [15_000, 25_000, 35_000, 50_000, 75_000, 100_000]
115
115
  y = [0.154, 0.283, 0.402, 0.55, 0.733, 0.843]
116
116