rubydns 1.0.3 → 2.0.0.pre.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +4 -0
  3. data/.travis.yml +9 -12
  4. data/Gemfile +4 -1
  5. data/README.md +49 -151
  6. data/Rakefile +2 -7
  7. data/examples/basic-dns.rb +24 -0
  8. data/examples/cname.rb +25 -0
  9. data/examples/flakey-dns.rb +2 -2
  10. data/examples/simple.rb +25 -0
  11. data/examples/soa-dns.rb +82 -0
  12. data/examples/test-dns-1.rb +83 -0
  13. data/examples/test-dns-2.rb +83 -0
  14. data/examples/wikipedia-dns.rb +4 -18
  15. data/lib/rubydns.rb +9 -23
  16. data/lib/rubydns/{server.rb → rule_based_server.rb} +2 -160
  17. data/lib/rubydns/version.rb +1 -1
  18. data/rubydns.gemspec +3 -6
  19. data/spec/rubydns/daemon_spec.rb +26 -22
  20. data/spec/rubydns/injected_supervisor_spec.rb +10 -7
  21. data/spec/rubydns/passthrough_spec.rb +31 -24
  22. data/spec/spec_helper.rb +43 -0
  23. metadata +21 -100
  24. data/lib/rubydns/chunked.rb +0 -34
  25. data/lib/rubydns/extensions/resolv.rb +0 -85
  26. data/lib/rubydns/extensions/string.rb +0 -28
  27. data/lib/rubydns/handler.rb +0 -188
  28. data/lib/rubydns/logger.rb +0 -31
  29. data/lib/rubydns/message.rb +0 -76
  30. data/lib/rubydns/resolver.rb +0 -294
  31. data/lib/rubydns/system.rb +0 -146
  32. data/lib/rubydns/transaction.rb +0 -204
  33. data/lib/rubydns/transport.rb +0 -75
  34. data/spec/rubydns/celluloid_bug_spec.rb +0 -92
  35. data/spec/rubydns/ipv6_spec.rb +0 -70
  36. data/spec/rubydns/message_spec.rb +0 -56
  37. data/spec/rubydns/origin_spec.rb +0 -106
  38. data/spec/rubydns/resolver_performance_spec.rb +0 -110
  39. data/spec/rubydns/resolver_spec.rb +0 -152
  40. data/spec/rubydns/server/bind9/generate-local.rb +0 -25
  41. data/spec/rubydns/server/bind9/local.zone +0 -5014
  42. data/spec/rubydns/server/bind9/named.conf +0 -14
  43. data/spec/rubydns/server/bind9/named.run +0 -0
  44. data/spec/rubydns/server/million.rb +0 -85
  45. data/spec/rubydns/server/rubydns.stackprof +0 -0
  46. data/spec/rubydns/server_performance_spec.rb +0 -136
  47. data/spec/rubydns/slow_server_spec.rb +0 -89
  48. data/spec/rubydns/socket_spec.rb +0 -77
  49. data/spec/rubydns/system_spec.rb +0 -60
  50. data/spec/rubydns/transaction_spec.rb +0 -138
  51. data/spec/rubydns/truncation_spec.rb +0 -59
@@ -1,75 +0,0 @@
1
- # Copyright, 2009, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
20
-
21
- require 'stringio'
22
- require 'ipaddr'
23
-
24
- require_relative 'message'
25
-
26
- module RubyDNS
27
- def self.address_family(host)
28
- return IPAddr.new(host).family
29
- end
30
-
31
- # A helper class for processing incoming network data.
32
- class BinaryStringIO < StringIO
33
- def initialize
34
- super
35
-
36
- set_encoding("BINARY")
37
- end
38
- end
39
-
40
- module StreamTransport
41
- def self.read_chunk(socket)
42
- # The data buffer:
43
- buffer = BinaryStringIO.new
44
-
45
- # First we need to read in the length of the packet
46
- while buffer.size < 2
47
- buffer.write socket.readpartial(1)
48
- end
49
-
50
- # Read in the length, the first two bytes:
51
- length = buffer.string.byteslice(0, 2).unpack('n')[0]
52
-
53
- # Read data until we have the amount specified:
54
- while (buffer.size - 2) < length
55
- required = (2 + length) - buffer.size
56
-
57
- # Read precisely the required amount:
58
- buffer.write socket.readpartial(required)
59
- end
60
-
61
- return buffer.string.byteslice(2, length)
62
- end
63
-
64
- def self.write_message(socket, message)
65
- write_chunk(socket, message.encode)
66
- end
67
-
68
- def self.write_chunk(socket, output_data)
69
- socket.write([output_data.bytesize].pack('n'))
70
- socket.write(output_data)
71
-
72
- return output_data.bytesize
73
- end
74
- end
75
- end
@@ -1,92 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
22
-
23
- require 'rubydns'
24
-
25
- module RubyDNS::CelluloidBugSpec
26
- describe RubyDNS::Resolver do
27
- context 'benchmark' do
28
- domains = %W(
29
- Facebook.com
30
- Twitter.com
31
- Google.com
32
- Youtube.com
33
- Wordpress.org
34
- Adobe.com
35
- Blogspot.com
36
- Wikipedia.org
37
- Linkedin.com
38
- Wordpress.com
39
- Yahoo.com
40
- Amazon.com
41
- Flickr.com
42
- Pinterest.com
43
- Tumblr.com
44
- W3.org
45
- Apple.com
46
- Myspace.com
47
- Vimeo.com
48
- Microsoft.com
49
- Youtu.be
50
- Qq.com
51
- Digg.com
52
- Baidu.com
53
- Stumbleupon.com
54
- Addthis.com
55
- Statcounter.com
56
- Feedburner.com
57
- TradeMe.co.nz
58
- Delicious.com
59
- Nytimes.com
60
- Reddit.com
61
- Weebly.com
62
- Bbc.co.uk
63
- Blogger.com
64
- Msn.com
65
- Macromedia.com
66
- Goo.gl
67
- Instagram.com
68
- Gov.uk
69
- Icio.us
70
- Yandex.ru
71
- Cnn.com
72
- Webs.com
73
- Google.de
74
- T.co
75
- Livejournal.com
76
- Imdb.com
77
- Mail.ru
78
- Jimdo.com
79
- )
80
-
81
- it 'should be faster than native resolver' do
82
- Celluloid.logger.level = Logger::ERROR
83
-
84
- resolver = RubyDNS::Resolver.new([[:udp, "8.8.8.8", 53], [:tcp, "8.8.8.8", 53]], timeout: 0.1)
85
-
86
- futures = domains.map { |domain| resolver.future.addresses_for(domain) }
87
-
88
- futures.map { |future| future.value }
89
- end
90
- end
91
- end
92
- end
@@ -1,70 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # Copyright, 2014, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
22
-
23
- require 'rubydns'
24
- require 'rubydns/system'
25
-
26
- module RubyDNS::IPv6Spec
27
- IN = Resolv::DNS::Resource::IN
28
-
29
- describe RubyDNS::TCPSocketHandler do
30
- before(:all) do
31
- Celluloid.shutdown
32
- Celluloid.boot
33
- end
34
-
35
- it "should create server with existing TCP socket" do
36
- @server = RubyDNS::run_server(:listen => [[:tcp, '::', 2002]], asynchronous: true) do
37
- resolver = RubyDNS::Resolver.new([[:udp, "8.8.8.8", 53], [:tcp, "8.8.8.8", 53]])
38
-
39
- match(/.*\.com/, IN::A) do |transaction|
40
- transaction.passthrough!(resolver)
41
- end
42
- end
43
-
44
- resolver = RubyDNS::Resolver.new([[:tcp, '::1', 2002]])
45
- response = resolver.query('google.com')
46
- expect(response.class).to be == RubyDNS::Message
47
- end
48
- end
49
-
50
- describe RubyDNS::UDPSocketHandler do
51
- before(:all) do
52
- Celluloid.shutdown
53
- Celluloid.boot
54
- end
55
-
56
- it "should create server with existing UDP socket" do
57
- @server = RubyDNS::run_server(:listen => [[:udp, '::', 2002]], asynchronous: true) do
58
- resolver = RubyDNS::Resolver.new([[:udp, "8.8.8.8", 53], [:tcp, "8.8.8.8", 53]])
59
-
60
- match(/.*\.com/, IN::A) do |transaction|
61
- transaction.passthrough!(resolver)
62
- end
63
- end
64
-
65
- resolver = RubyDNS::Resolver.new([[:udp, '::1', 2002]])
66
- response = resolver.query('google.com')
67
- expect(response.class).to be == RubyDNS::Message
68
- end
69
- end
70
- end
@@ -1,56 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
22
-
23
- require 'rubydns'
24
- require 'base64'
25
-
26
- module RubyDNS::MessageSpec
27
- describe RubyDNS::Message do
28
- it "should be decoded correctly" do
29
- data = Base64.decode64(<<-EOF)
30
- HQCBgAABAAgAAAABA3d3dwV5YWhvbwNjb20AAAEAAcAMAAUAAQAAASwADwZm
31
- ZC1mcDMDd2cxAWLAEMArAAUAAQAAASwACQZkcy1mcDPAMsBGAAUAAQAAADwA
32
- FQ5kcy1hbnktZnAzLWxmYgN3YTHANsBbAAUAAQAAASwAEg9kcy1hbnktZnAz
33
- LXJlYWzAasB8AAEAAQAAADwABGKK/B7AfAABAAEAAAA8AARii7SVwHwAAQAB
34
- AAAAPAAEYou3GMB8AAEAAQAAADwABGKK/W0AACkQAAAAAAAAAA==
35
- EOF
36
-
37
- message = RubyDNS::decode_message(data)
38
- expect(message.class).to be == RubyDNS::Message
39
- expect(message.id).to be == 0x1d00
40
-
41
- expect(message.question.count).to be == 1
42
- expect(message.answer.count).to be == 8
43
- expect(message.authority.count).to be == 0
44
- expect(message.additional.count).to be == 1
45
- end
46
-
47
- it "should fail to decode due to bad AAAA length" do
48
- data = Base64.decode64(<<-EOF)
49
- 6p6BgAABAAEAAAABCGJhaWNhaWNuA2NvbQAAHAABwAwAHAABAAABHgAEMhd7
50
- dwAAKRAAAAAAAAAA
51
- EOF
52
-
53
- expect{RubyDNS::decode_message(data)}.to raise_error(RubyDNS::DecodeError)
54
- end
55
- end
56
- end
@@ -1,106 +0,0 @@
1
- #!/usr/bin/env rspec
2
-
3
- # Copyright, 2014, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
22
-
23
- require 'rubydns'
24
-
25
- module RubyDNS::OriginSpec
26
- describe RubyDNS::Resolver do
27
- it "should generate fully qualified domain name with specified origin" do
28
- resolver = RubyDNS::Resolver.new([], origin: "foo.bar.")
29
-
30
- fully_qualified_name = resolver.fully_qualified_name("baz")
31
-
32
- expect(fully_qualified_name).to be_absolute
33
- expect(fully_qualified_name.to_s).to be == "baz.foo.bar."
34
- end
35
- end
36
-
37
- describe Resolv::DNS::Name do
38
- let(:name) {Resolv::DNS::Name.create("foo.bar")}
39
-
40
- it "should be relative" do
41
- expect(name).to_not be_absolute
42
- expect(name.to_s).to be == "foo.bar"
43
- end
44
-
45
- it "should add the specified origin" do
46
- fully_qualified_name = name.with_origin("org")
47
-
48
- expect(fully_qualified_name.to_a.size).to be 3
49
- expect(fully_qualified_name).to be_absolute
50
- expect(fully_qualified_name.to_s).to be == "foo.bar.org."
51
- end
52
-
53
- it "should handle nil origin as absolute" do
54
- fully_qualified_name = name.with_origin(nil)
55
-
56
- expect(fully_qualified_name.to_a.size).to be 2
57
- expect(fully_qualified_name).to be_absolute
58
- expect(fully_qualified_name.to_s).to be == "foo.bar."
59
- end
60
-
61
- it "should handle empty origin as absolute" do
62
- fully_qualified_name = name.with_origin('')
63
-
64
- expect(fully_qualified_name.to_a.size).to be 2
65
- expect(fully_qualified_name).to be_absolute
66
- expect(fully_qualified_name.to_s).to be == "foo.bar."
67
- end
68
- end
69
-
70
- describe Resolv::DNS::Name do
71
- let(:name) {Resolv::DNS::Name.create("foo.bar.")}
72
-
73
- it "should be absolute" do
74
- expect(name).to be_absolute
75
- expect(name.to_s).to be == "foo.bar."
76
- end
77
-
78
- it "should remove the specified origin" do
79
- relative_name = name.without_origin("bar")
80
-
81
- expect(relative_name.to_a.size).to be 1
82
- expect(relative_name).to_not be_absolute
83
- expect(relative_name.to_s).to be == "foo"
84
- end
85
-
86
- it "should not remove nil origin but become relative" do
87
- relative_name = name.without_origin(nil)
88
-
89
- expect(relative_name.to_a.size).to be 2
90
- expect(relative_name).to_not be_absolute
91
- expect(relative_name.to_s).to be == "foo.bar"
92
- end
93
-
94
- it "should not remove empty string origin but become relative" do
95
- relative_name = name.without_origin('')
96
-
97
- expect(relative_name.to_a.size).to be 2
98
- expect(relative_name).to_not be_absolute
99
- expect(relative_name.to_s).to be == "foo.bar"
100
- end
101
-
102
- it "should not raise an exception when origin isn't valid" do
103
- expect{name.without_origin('bob')}.to raise_exception(Resolv::DNS::OriginError)
104
- end
105
- end
106
- end
@@ -1,110 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
22
-
23
- require 'rubydns'
24
-
25
- module RubyDNS::ResolverPerformanceSpec
26
- describe RubyDNS::Resolver do
27
- context 'benchmark' do
28
- domains = %W{
29
- Facebook.com
30
- Twitter.com
31
- Google.com
32
- Youtube.com
33
- Wordpress.org
34
- Adobe.com
35
- Blogspot.com
36
- Wikipedia.org
37
- Linkedin.com
38
- Wordpress.com
39
- Yahoo.com
40
- Amazon.com
41
- Flickr.com
42
- Pinterest.com
43
- Tumblr.com
44
- W3.org
45
- Apple.com
46
- Myspace.com
47
- Vimeo.com
48
- Microsoft.com
49
- Youtu.be
50
- Qq.com
51
- Digg.com
52
- Baidu.com
53
- Stumbleupon.com
54
- Addthis.com
55
- Statcounter.com
56
- Feedburner.com
57
- TradeMe.co.nz
58
- Delicious.com
59
- Nytimes.com
60
- Reddit.com
61
- Weebly.com
62
- Bbc.co.uk
63
- Blogger.com
64
- Msn.com
65
- Macromedia.com
66
- Goo.gl
67
- Instagram.com
68
- Gov.uk
69
- Icio.us
70
- Yandex.ru
71
- Cnn.com
72
- Webs.com
73
- Google.de
74
- T.co
75
- Livejournal.com
76
- Imdb.com
77
- Mail.ru
78
- Jimdo.com
79
- }
80
-
81
- before do
82
- require 'benchmark'
83
- end
84
-
85
- it 'should be faster than native resolver' do
86
- Celluloid.logger.level = Logger::ERROR
87
-
88
- Benchmark.bm(20) do |x|
89
- a = x.report("RubyDNS::Resolver") do
90
- resolver = RubyDNS::Resolver.new([[:udp, "8.8.8.8", 53], [:tcp, "8.8.8.8", 53]])
91
-
92
- futures = domains.collect{|domain| resolver.future.addresses_for(domain)}
93
-
94
- futures.collect{|future| future.value}
95
- end
96
-
97
- b = x.report("Resolv::DNS") do
98
- resolver = Resolv::DNS.new(:nameserver => "8.8.8.8")
99
-
100
- resolved = domains.collect do |domain|
101
- [domain, resolver.getaddresses(domain)]
102
- end
103
- end
104
-
105
- expect(a.real).to be < b.real
106
- end
107
- end
108
- end
109
- end
110
- end