From 4fbd9d98e550aa9a8fab8b28c39233ce9f8e7201 Mon Sep 17 00:00:00 2001 From: Gauthier Delacroix Date: Mon, 15 Sep 2014 18:21:43 +0200 Subject: Add Mongoid support --- ipaddress.gemspec | 2 ++ lib/ipaddress.rb | 1 + lib/ipaddress/mongoid.rb | 75 +++++++++++++++++++++++++++++++++++++++++ test/ipaddress/mongoid_test.rb | 76 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 154 insertions(+) create mode 100644 lib/ipaddress/mongoid.rb create mode 100644 test/ipaddress/mongoid_test.rb diff --git a/ipaddress.gemspec b/ipaddress.gemspec index 41af7bf..7b6e151 100644 --- a/ipaddress.gemspec +++ b/ipaddress.gemspec @@ -32,9 +32,11 @@ Gem::Specification.new do |s| "lib/ipaddress/ipv4.rb", "lib/ipaddress/ipv6.rb", "lib/ipaddress/prefix.rb", + "lib/ipaddress/mongoid.rb", "test/ipaddress/ipv4_test.rb", "test/ipaddress/ipv6_test.rb", "test/ipaddress/prefix_test.rb", + "test/ipaddress/mongoid_test.rb", "test/ipaddress_test.rb", "test/test_helper.rb" ] diff --git a/lib/ipaddress.rb b/lib/ipaddress.rb index 7631952..e2161e1 100644 --- a/lib/ipaddress.rb +++ b/lib/ipaddress.rb @@ -14,6 +14,7 @@ require 'ipaddress/ipv4' require 'ipaddress/ipv6' +require 'ipaddress/mongoid' if defined?(Mongoid) module IPAddress diff --git a/lib/ipaddress/mongoid.rb b/lib/ipaddress/mongoid.rb new file mode 100644 index 0000000..3af880a --- /dev/null +++ b/lib/ipaddress/mongoid.rb @@ -0,0 +1,75 @@ +module IPAddress + + # + # Mongoid field serialization + # + # IPAddress objects are converted to String + # + # IPAddress.mongoize IPAddress.parse("172.16.10.1") + # #=> "172.16.10.1" + # + # Prefix will be removed from host adresses + # + # IPAddress.mongoize "172.16.10.1/32" + # #=> "172.16.10.1" + # + # Prefix will be kept for network addresses + # + # IPAddress.mongoize "172.16.10.1/24" + # #=> "172.16.10.1/24" + # + # IPv6 addresses will be stored uncompressed to ease DB search and sorting + # + # IPAddress.mongoize "2001:db8::8:800:200c:417a" + # #=> "2001:0db8:0000:0000:0008:0800:200c:417a" + # IPAddress.mongoize "2001:db8::8:800:200c:417a/64" + # #=> "2001:0db8:0000:0000:0008:0800:200c:417a/64" + # + # Invalid addresses will be serialized as nil + # + # IPAddress.mongoize "invalid" + # #=> nil + # IPAddress.mongoize "" + # #=> nil + # IPAddress.mongoize 1 + # #=> nil + # IPAddress.mongoize nil + # #=> nil + # + def self.mongoize(ipaddress) + ipaddress = self.parse(ipaddress) unless ipaddress.is_a?(IPAddress) + if ipaddress.bits.length == ipaddress.prefix + ipaddress.address + elsif ipaddress.is_a?(IPAddress::IPv6) + ipaddress.to_string_uncompressed + else + ipaddress.to_string + end + rescue ArgumentError + nil + end + + # + # Mongoid field deserialization + # + def self.demongoize(string) + parse(string) + rescue ArgumentError + nil + end + + # + # Delegates to IPAddress.mongoize + # + def self.evolve(ipaddress) + mongoize(ipaddress) + end + + # + # Sends self object to IPAddress#mongoize + # + def mongoize + IPAddress.mongoize(self) + end + +end \ No newline at end of file diff --git a/test/ipaddress/mongoid_test.rb b/test/ipaddress/mongoid_test.rb new file mode 100644 index 0000000..175e918 --- /dev/null +++ b/test/ipaddress/mongoid_test.rb @@ -0,0 +1,76 @@ +require 'test_helper' +require 'ipaddress/mongoid' + +class MongoidTest < Test::Unit::TestCase + + def setup + @valid_host4 = "172.16.10.1" + @valid_host6 = "2001:0db8:0000:0000:0008:0800:200c:417a" + @valid_host6_compressed = IPAddress::IPv6.compress(@valid_host6) + @valid_network4 = "#{@valid_host4}/24" + @valid_network6 = "#{@valid_host6}/96" + @valid_network6_compressed = "#{@valid_host6_compressed}/96" + @host4 = IPAddress.parse(@valid_host4) + @host6 = IPAddress.parse(@valid_host6) + @network4 = IPAddress.parse(@valid_network4) + @network6 = IPAddress.parse(@valid_network6) + @invalid_values = [nil, "", 1, "invalid"] + end + + def test_mongoize + # Instance method should be delegated to class method + assert_equal @host4.mongoize, IPAddress.mongoize(@host4) + assert_equal @network4.mongoize, IPAddress.mongoize(@network4) + + # Hosts addresses should be stored without prefix + assert_equal @valid_host4, IPAddress.mongoize(@host4) + assert_equal @valid_host6, IPAddress.mongoize(@host6) + assert_equal @valid_host4, IPAddress.mongoize("#{@host4}/32") + assert_equal @valid_host6, IPAddress.mongoize("#{@host6}/128") + + # Network addresses should be stored with their prefix + assert_equal @valid_network4, IPAddress.mongoize(@network4) + assert_equal @valid_network6, IPAddress.mongoize(@network6) + + # IPv6 addresses should always be stored uncompressed + assert_equal @valid_host6, IPAddress.mongoize(@valid_host6_compressed) + assert_equal @valid_network6, IPAddress.mongoize(@valid_network6_compressed) + + @invalid_values.each do |invalid_value| + # Invalid address should not raise error + assert_nothing_raised {IPAddress.mongoize(invalid_value)} + + # Invalid addresses should serialize to nil + assert_equal nil, IPAddress.mongoize(invalid_value) + end + end + + def test_demongoize + # Valid stored values should be loaded with expected IPAddress type + assert_instance_of IPAddress::IPv4, IPAddress.demongoize(@valid_host4) + assert_instance_of IPAddress::IPv6, IPAddress.demongoize(@valid_host6) + assert_instance_of IPAddress::IPv4, IPAddress.demongoize(@valid_network4) + assert_instance_of IPAddress::IPv6, IPAddress.demongoize(@valid_network6) + + # Valid stored values should be loaded as the original IPAddress object + assert_equal @host4, IPAddress.demongoize(@valid_host4) + assert_equal @host6, IPAddress.demongoize(@valid_host6) + assert_equal @network4, IPAddress.demongoize(@valid_network4) + assert_equal @network6, IPAddress.demongoize(@valid_network6) + + @invalid_values.each do |invalid_value| + # Invalid stored values should not raise error + assert_nothing_raised {IPAddress.demongoize(invalid_value)} + + # Invalid stored value should be loaded as nil + assert_equal nil, IPAddress.demongoize(invalid_value) + end + end + + def test_evolve + # evolve should delegate to mongoize + assert_equal IPAddress.mongoize(@valid_host4), IPAddress.evolve(@valid_host4) + assert_equal IPAddress.mongoize(@valid_network4), IPAddress.evolve(@valid_network4) + end + +end \ No newline at end of file -- cgit v1.2.1