diff --git a/History.rdoc b/History.rdoc index 9e7ef55..b8e5e92 100644 --- a/History.rdoc +++ b/History.rdoc @@ -1,11 +1,14 @@ -=== 0.2.0 / 2009-??-?? +=== 0.2.0 / 2009-11-05 * Added a mechanism for converting from one format/schema to another. * Added Rubygems format, along with conversions to and from the standard format. * Slight change to value comparison semantics. Value#eql? returns true only if the schemas are the same, whereas Value#== and the greater than and less than comparisons attempt to compare the semantic value, and thus may perform automatic schema conversion on the RHS. +* Values now include Comparable. +* Values can now be marshalled and unmarshalled. * Schemas can now add custom methods to value objects. * Added default field settings to schema DSL. * Implemented #=== for schemas and formats. +* Merged Formats namespace into Format. Versionomy::Formats is now a (deprecated) alias for Versionomy::Format. === 0.1.3 / 2009-10-29 diff --git a/lib/versionomy.rb b/lib/versionomy.rb index b4bc728..25e9759 100644 --- a/lib/versionomy.rb +++ b/lib/versionomy.rb @@ -52,15 +52,13 @@ 'format', 'format/base', 'format/delimiter', - 'formats', - 'formats/standard', - 'formats/rubygems', + 'format/standard', + 'format/rubygems', 'value', 'conversion', 'conversion/base', 'conversion/parsing', - 'conversions', - 'conversions/rubygems', + 'conversion/rubygems', 'interface', 'version', ] diff --git a/lib/versionomy/conversion.rb b/lib/versionomy/conversion.rb index 68e16ef..d897f11 100644 --- a/lib/versionomy/conversion.rb +++ b/lib/versionomy/conversion.rb @@ -39,14 +39,31 @@ module Versionomy # === Conversion between version schemas. # + # Conversions are algorithms for converting from one schema to another. + # This is useful for performing conversions as well as comparing version + # numbers that use different schemas. # + # To implement a conversion algorithm, implement the API defined by + # Versionomy::Conversion::Base. Then, register your conversion by calling + # Versionomy::Conversion#register. You will need to specify which schemas + # (from and to) that your conversion should handle. From that point on, + # whenever Versionomy needs to convert a value between those two schemas, + # it will use your conversion. You can register the same conversion object + # for multiple pairs of schemas, but you can register only one conversion + # object for any pair. module Conversion + @registry = ::Hash.new + class << self - # Convert the given value to the given format. + # Convert the given value to the given format. This is identical to + # calling value_.convert(format_, convert_params_). + # + # The format may be specified as a format object or as the name of a + # format in the Format registry. # # Raises Versionomy::Errors::ConversionError if the value could not # be converted. @@ -56,6 +73,64 @@ def convert(value_, format_, convert_params_=nil) end + # Get a conversion capable of converting between the given schemas. + # + # The schemas may be specified as format names, Format objects, + # schema wrapper objects, or the root field of the schema. + # + # If strict is set to false, returns nil if no such conversion could + # be found. If strict is set to true, may raise one of these errors: + # + # Raises Versionomy::Errors::UnknownFormatError if a format was + # specified by name but the name is not known. + # + # Raises Versionomy::Errors::UnknownConversionError if the formats + # were recognized but no conversion was found to handle them. + + def get(from_schema_, to_schema_, strict_=false) + key_ = _get_key(from_schema_, to_schema_) + conversion_ = @registry[key_] + if strict_ && conversion_.nil? + raise Errors::UnknownConversionError + end + conversion_ + end + + + # Register the given conversion as the handler for the given schemas. + # + # The schemas may be specified as format names, Format objects, + # schema wrapper objects, or the root field of the schema. + # + # Raises Versionomy::Errors::ConversionRedefinedError if a conversion + # has already been registered for the given schemas. + # + # Raises Versionomy::Errors::UnknownFormatError if a format was + # specified by name but the name is not known. + + def register(from_schema_, to_schema_, conversion_) + key_ = _get_key(from_schema_, to_schema_) + if @registry.include?(key_) + raise Errors::ConversionRedefinedError + end + @registry[key_] = conversion_ + end + + + private + + def _get_key(from_schema_, to_schema_) # :nodoc: + [_get_schema(from_schema_), _get_schema(to_schema_)] + end + + def _get_schema(schema_) # :nodoc: + schema_ = Format.get(schema_, true) if schema_.kind_of?(::String) || schema_.kind_of?(::Symbol) + schema_ = schema_.schema if schema_.respond_to?(:schema) + schema_ = schema_.root_field if schema_.respond_to?(:root_field) + schema_ + end + + end end diff --git a/lib/versionomy/conversion/base.rb b/lib/versionomy/conversion/base.rb index 18df5e7..e0b6fcb 100644 --- a/lib/versionomy/conversion/base.rb +++ b/lib/versionomy/conversion/base.rb @@ -49,8 +49,10 @@ module Conversion class Base - # Convert the given value. - # Returns an equivalent value in the to_schema. + # Returns a value equivalent to the given value in the given format. + # + # The convert_params may be interpreted differently for different + # conversion implementations. # # Raises Versionomy::Errors::ConversionError if the conversion failed. @@ -59,6 +61,15 @@ def convert_value(value_, format_, convert_params_=nil) end + def inspect # :nodoc: + "#<#{self.class}:0x#{object_id.to_s(16)}>" + end + + def to_s # :nodoc: + inspect + end + + end diff --git a/lib/versionomy/conversion/parsing.rb b/lib/versionomy/conversion/parsing.rb index 2599134..403f7ef 100644 --- a/lib/versionomy/conversion/parsing.rb +++ b/lib/versionomy/conversion/parsing.rb @@ -47,37 +47,59 @@ module Conversion class Parsing - # Create an instance of this base conversion, with the given from and - # to schemas. + # Create a parsing conversion. + # + # By default, this just unparses and reparses using the default + # parse settings. In some cases, this may be enough, but you may + # wish to improve the reliability of the conversion by tweaking the + # parsing settings. To do so, pass a block to the new method, and + # call methds of Versionomy::Conversion::Parsing::Builder in that + # block. - def initialize(opts_={}, &block_) - @parse_params = opts_[:parse_params] + def initialize(&block_) if block_ builder_ = Builder.new ::Blockenspiel.invoke(block_, builder_) @string_modifier = builder_._get_string_modifier @unparse_params_modifier = builder_._get_unparse_params_modifier - @parse_params ||= builder_._get_parse_params + @parse_params_generator ||= builder_._get_parse_params_generator end end - # Convert the given value. The value must match the from_schema. - # Returns an equivalent value in the to_schema. + def inspect # :nodoc: + "#<#{self.class}:0x#{object_id.to_s(16)}>" + end + + def to_s # :nodoc: + inspect + end + + + # Returns a value equivalent to the given value in the given format. + # + # The convert_params are passed to this conversion's customization + # blocks (if any). # # Raises Versionomy::Errors::ConversionError if the conversion failed. + # Typically, this is due to a failure of the parsing or unparsing. def convert_value(value_, format_, convert_params_=nil) begin unparse_params_ = value_.unparse_params if @unparse_params_modifier - unparse_params_ = @unparse_params_modifier.call(unparse_params_) + unparse_params_ = @unparse_params_modifier.call(unparse_params_, convert_params_) end string_ = value_.unparse(unparse_params_) if @string_modifier - string_ = @string_modifier.call(string_) + string_ = @string_modifier.call(string_, convert_params_) + end + if @parse_params_generator + parse_params_ = @parse_params_generator.call(convert_params_) + else + parse_params_ = nil end - new_value_ = format_.parse(string_, @parse_params) + new_value_ = format_.parse(string_, parse_params_) return new_value_ rescue Errors::UnparseError => ex_ raise Errors::ConversionError, "Unparsing failed: #{ex_.inspect}" @@ -87,33 +109,56 @@ def convert_value(value_, format_, convert_params_=nil) end + # Call methods of this class in the block passed to + # Versionomy::Conversion::Parsing#new to fine-tune the behavior of + # the converter. + class Builder include ::Blockenspiel::DSL - def initialize + def initialize # :nodoc: @string_modifier = nil - @parse_params = nil + @parse_params_generator = nil @unparse_params_modifier = nil end - def parse_params(params_) - @parse_params = params_ - end - + # Provide a block that generates the params used to parse the new + # value. The block should take one parameter, the convert_params + # passed to convert_value (which may be nil). It should return the + # parse params that should be used. - def to_modify_string(&block_) - @string_modifier = block_ + def to_generate_parse_params(&block_) + @parse_params_generator = block_ end + # Provide a block that can modify the params used to unparse the + # old value. The block should take two parameters: first, the + # original unparse params from the old value (which may be nil), + # and second, the convert_params passed to convert_value (which + # may also be nil). It should return the unparse params that + # should actually be used. + def to_modify_unparse_params(&block_) @unparse_params_modifier = block_ end + # Provide a block that can modify the unparsed string prior to + # it being passed to the parser. The block should take two + # parameters: first, the string resulting from unparsing the old + # value, and second, the convert_params passed to convert_value + # (which may be nil). It should return the string to be parsed to + # get the new value. + + def to_modify_string(&block_) + @string_modifier = block_ + end + + def _get_string_modifier # :nodoc: @string_modifier end @@ -122,8 +167,8 @@ def _get_unparse_params_modifier # :nodoc: @unparse_params_modifier end - def _get_parse_params # :nodoc: - @parse_params + def _get_parse_params_generator # :nodoc: + @parse_params_generator end end diff --git a/lib/versionomy/conversion/rubygems.rb b/lib/versionomy/conversion/rubygems.rb new file mode 100644 index 0000000..b51b4af --- /dev/null +++ b/lib/versionomy/conversion/rubygems.rb @@ -0,0 +1,137 @@ +# ----------------------------------------------------------------------------- +# +# Versionomy standard format implementation +# +# ----------------------------------------------------------------------------- +# Copyright 2008-2009 Daniel Azuma +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the copyright holder, nor the names of any other +# contributors to this software, may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# ----------------------------------------------------------------------------- +; + + +module Versionomy + + module Conversion + + + # This is a namespace for the implementation of the conversion between + # the rubygems and standard formats. + + module Rubygems + + + # Create the conversion from standard to rubygems format. + # This method is called internally when Versionomy initializes itself, + # and you should not need to call it again. It is documented, however, + # so that you can inspect its source code from RDoc, since the source + # contains useful examples of how to use the conversion DSLs. + + def self.create_standard_to_rubygems + + # We'll use a parsing conversion to do this conversion. + Conversion::Parsing.new do + + # We're going to modify how the standard format version is + # unparsed, so the rubygems format will have a better chance + # of parsing it. + to_modify_unparse_params do |params_, convert_params_| + + params_ ||= {} + + # If the standard format version has a prerelease notation, + # make sure it is set off using a delimiter that the rubygems + # format can recognized. So instead of "1.0b2", we force the + # unparsing to generate "1.0.b.2". + params_[:release_type_delim] = '.' + params_[:release_type_postdelim] = '.' + + # If the standard format version has a patchlevel notation, + # force it to use the default number rather than letter style. + # So instead of "1.2c", we force the unparsing to generate + # "1.2-3". + params_[:patchlevel_style] = nil + + # If the standard format version has a patchlevel notation, + # force it to use the default delimiter of "-" so the rubygems + # format will recognize it. So instead of "1.9.1p243", we force + # the unparsing to generate "1.9.1-243". + params_[:patchlevel_delim] = nil + + params_ + end + + # Standard formats sometimes allow hyphens and spaces in field + # delimiters, but the rubygems format requires periods. So modify + # the unparsed string to conform to rubygems's expectations. + to_modify_string do |str_, convert_params_| + str_.gsub(/[\.\s-]+/, '.') + end + + end + + end + + + # Create the conversion from rubygems to standard format. + # This method is called internally when Versionomy initializes itself, + # and you should not need to call it again. It is documented, however, + # so that you can inspect its source code from RDoc, since the source + # contains useful examples of how to use the conversion DSLs. + + def self.create_rubygems_to_standard + + # We'll use a parsing conversion to do this conversion. + Conversion::Parsing.new do + + # The standard format generally will understand the rubygems + # format, except that the standard format supports only four + # fields (plus prerelease versions or patchlevel). So cause the + # parser to error out if rubygems unparses too many fields. + to_generate_parse_params do |convert_params_| + {:extra_characters => :error} + end + + end + + end + + + unless Conversion.get(:standard, :rubygems) + Conversion.register(:standard, :rubygems, create_standard_to_rubygems) + end + unless Conversion.get(:rubygems, :standard) + Conversion.register(:rubygems, :standard, create_rubygems_to_standard) + end + + + end + + + end + +end diff --git a/lib/versionomy/conversions.rb b/lib/versionomy/conversions.rb deleted file mode 100644 index d9e29eb..0000000 --- a/lib/versionomy/conversions.rb +++ /dev/null @@ -1,100 +0,0 @@ -# ----------------------------------------------------------------------------- -# -# Versionomy conversion interface and registry -# -# ----------------------------------------------------------------------------- -# Copyright 2008-2009 Daniel Azuma -# -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# * Neither the name of the copyright holder, nor the names of any other -# contributors to this software, may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# ----------------------------------------------------------------------------- -; - - -module Versionomy - - - # === Version number conversions regsitry. - # - # Use the methods of this module to register conversions with Versionomy. - # - # This module also serves as a convenient namespace for implementations - # of conversions. - - module Conversions - - @registry = ::Hash.new - - class << self - - - # Get a conversion capable of converting between the given schemas. - # Returns nil if no such conversion could be found. - - def get(from_schema_, to_schema_, strict_=false) - key_ = _get_key(from_schema_, to_schema_) - conversion_ = @registry[key_] - if strict_ && conversion_.nil? - raise Errors::UnknownConversionError - end - conversion_ - end - - - # Register the given conversion. - # - # Raises Versionomy::Errors::ConversionRedefinedError if a conversion - # has already been registered for the given schemas. - - def register(from_schema_, to_schema_, conversion_) - key_ = _get_key(from_schema_, to_schema_) - if @registry.include?(key_) - raise Errors::ConversionRedefinedError - end - @registry[key_] = conversion_ - end - - - private - - def _get_key(from_schema_, to_schema_) # :nodoc: - [_get_schema(from_schema_), _get_schema(to_schema_)] - end - - def _get_schema(schema_) # :nodoc: - schema_ = Formats.get(schema_, true) if schema_.kind_of?(::String) || schema_.kind_of?(::Symbol) - schema_ = schema_.schema if schema_.respond_to?(:schema) - schema_ = schema_.root_field if schema_.respond_to?(:root_field) - schema_ - end - - - end - - end - - -end diff --git a/lib/versionomy/conversions/rubygems.rb b/lib/versionomy/conversions/rubygems.rb deleted file mode 100644 index e2b24b7..0000000 --- a/lib/versionomy/conversions/rubygems.rb +++ /dev/null @@ -1,88 +0,0 @@ -# ----------------------------------------------------------------------------- -# -# Versionomy standard format implementation -# -# ----------------------------------------------------------------------------- -# Copyright 2008-2009 Daniel Azuma -# -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# * Neither the name of the copyright holder, nor the names of any other -# contributors to this software, may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# ----------------------------------------------------------------------------- -; - - -module Versionomy - - module Conversions - - - # This module contains methods that create conversions between the - # standard and rubygems formats. - - module Rubygems - - class << self - - - # Create and register the rubygems conversions. - - def create_and_register - rubygems_ = Formats.get(:rubygems, true) - standard_ = Formats.get(:standard, true) - unless Conversions.get(standard_, rubygems_) - conversion_ = Conversion::Parsing.new do - to_modify_unparse_params do |params_| - params_[:release_type_delim] = '.' if params_[:release_type_delim].to_s.length == 0 - params_[:release_type_postdelim] = '.' if params_[:release_type_postdelim].to_s.length == 0 - params_[:patchlevel_delim] = nil - params_ - end - end - Conversions.register(standard_, rubygems_, conversion_) - end - unless Conversions.get(rubygems_, standard_) - conversion_ = Conversion::Parsing.new do - to_modify_string do |str_| - str_.gsub(/[^0-9a-zA-Z\s-]+/, '.') - end - parse_params(:extra_characters => :error) - end - Conversions.register(rubygems_, standard_, conversion_) - end - end - - - end - - - create_and_register - - end - - - end - -end diff --git a/lib/versionomy/errors.rb b/lib/versionomy/errors.rb index a405a19..76b2a73 100644 --- a/lib/versionomy/errors.rb +++ b/lib/versionomy/errors.rb @@ -128,7 +128,7 @@ class FormatRedefinedError < VersionomyError end - # Raised by the Formats registry if you try to retrieve a format with + # Raised by the Format registry if you try to retrieve a format with # an unrecognized name in strict mode. class UnknownFormatError < VersionomyError @@ -155,6 +155,12 @@ class ConversionRedefinedError < VersionomyError end + # Raised when serialization or deserialization fails. + + class SerializationError < VersionomyError + end + + end end diff --git a/lib/versionomy/format.rb b/lib/versionomy/format.rb index 2c9829d..d95a69f 100644 --- a/lib/versionomy/format.rb +++ b/lib/versionomy/format.rb @@ -48,7 +48,7 @@ module Versionomy # only that schema's version numbers. # # Under many circumstances, you should use the standard format, which - # can be retrieved by calling Versionomy::Formats#standard. This format + # can be retrieved by calling Versionomy::Format#standard. This format # understands most common version numbers, including prerelease # (e.g. alpha, beta, release candidate, etc.) forms and patchlevels. # @@ -58,11 +58,67 @@ module Versionomy # parsers for many version number formats. # # Formats may be registered with Versionomy and given a name using the - # methods of this Versionomy::Formats. This allows version numbers to be - # serialized with their format. + # methods of this module. This allows version numbers to be serialized + # with their format. + # + # Finally, this module serves as a namespace for format implementations. module Format + + @names_to_formats = ::Hash.new + @formats_to_names = ::Hash.new + + class << self + + + # Get the format with the given name. + # + # If the given name has not been defined, and strict is set to true, + # raises Versionomy::Errors::UnknownFormatError. If strict is set to + # false, returns nil if the given name has not been defined. + + def get(name_, strict_=false) + format_ = @names_to_formats[name_.to_s] + if format_.nil? && strict_ + raise Errors::UnknownFormatError, name_ + end + format_ + end + + + # Register the given format under the given name. + # + # Raises Versionomy::Errors::FormatRedefinedError if the name has + # already been defined. + + def register(name_, format_) + name_ = name_.to_s + if @names_to_formats.include?(name_) + raise Errors::FormatRedefinedError, name_ + end + @names_to_formats[name_] = format_ + @formats_to_names[format_.object_id] = name_ + end + + + # Get the canonical name for the given format, as a string. + # This is the first name the format was registered under. + # Returns nil if this format was never registered. + + def canonical_name_for(format_) + @formats_to_names[format_.object_id] + end + + + end + end + # Versionomy::Formats is an alias for Versionomy::Format, for backward + # compatibility with version 0.1.0 code. It is deprecated; use + # Versionomy::Format instead. + Formats = Format + + end diff --git a/lib/versionomy/format/base.rb b/lib/versionomy/format/base.rb index d31fa4d..4c25089 100644 --- a/lib/versionomy/format/base.rb +++ b/lib/versionomy/format/base.rb @@ -63,6 +63,15 @@ def initialize(schema_) end + def inspect # :nodoc: + "#<#{self.class}:0x#{object_id.to_s(16)} schema=#{@schema.inspect}>" + end + + def to_s # :nodoc: + inspect + end + + # Returns the schema understood by this format. def schema diff --git a/lib/versionomy/format/delimiter.rb b/lib/versionomy/format/delimiter.rb index 05c56a0..16fbb63 100644 --- a/lib/versionomy/format/delimiter.rb +++ b/lib/versionomy/format/delimiter.rb @@ -70,7 +70,7 @@ module Format # the parse and unparse methods for details. # # For a usage example, see the definition of the standard format in - # Versionomy::Formats#_create_standard. + # Versionomy::Format::Standard#create. class Delimiter < Base @@ -412,7 +412,7 @@ def initialize(schema_, field_handlers_, default_parse_params_, default_unparse_ # # The standard format uses styles to preserve the different # syntaxes for the release_type field. See the source code in - # Versionomy::Formats#_create_standard for this example. + # Versionomy::Format::Standard#create for this example. def field(name_, opts_={}, &block_) name_ = name_.to_sym diff --git a/lib/versionomy/formats/rubygems.rb b/lib/versionomy/format/rubygems.rb similarity index 78% rename from lib/versionomy/formats/rubygems.rb rename to lib/versionomy/format/rubygems.rb index 1edafe0..56bca48 100644 --- a/lib/versionomy/formats/rubygems.rb +++ b/lib/versionomy/format/rubygems.rb @@ -36,7 +36,7 @@ module Versionomy - module Formats + module Format # Get the rubygems format. @@ -45,14 +45,17 @@ module Formats # The rubygems format is designed to be parse-compatible with the # Gem::Version class used in rubygems. # - # For the exact annotated definition of the standard schema and format, - # see the source code for Versionomy::Formats::Rubygems#_create. + # For the exact annotated definition of the rubygems schema and format, + # see the source code for Versionomy::Format::Rubygems#create. def self.rubygems get('rubygems') end + # This is a namespace for the implementation of the Rubygems schema + # and format. + module Rubygems @@ -64,7 +67,21 @@ module ExtraMethods # Returns true if the version is a prerelease version def prerelease? - values_array.any?{ |val_| val_.kind_of?(String) } + values_array.any?{ |val_| val_.kind_of?(::String) } + end + + + # Returns the release for this version. + # For example, converts "1.2.0.a.1" to "1.2.0". + # Non-prerelease versions return themselves. + + def release + values_ = [] + self.each_field_object do |field_, val_| + break unless val_.kind_of?(::Integer) + values_ << val_ + end + Value.new(values_, self.format, self.unparse_params) end @@ -78,7 +95,7 @@ def prerelease? # contains useful examples of how to use the schema and format # definition DSLs. - def self._create + def self.create # The following is the definition of the rubygems schema schema_ = Schema.create do @@ -117,7 +134,7 @@ def self._create # The first field has the default value of 1. All other fields # have a default value of 0. Thus, the default version number # overall is "1.0". - field(:field0, :type => :string, :default_value => 1) do + field(:field0, :type => :integer, :default_value => 1) do field(:field1, :type => :string) do field(:field2, :type => :string) do field(:field3, :type => :string) do @@ -134,7 +151,7 @@ def self._create end # Add the methods in this module to each value - add_module(Formats::Rubygems::ExtraMethods) + add_module(Format::Rubygems::ExtraMethods) end # The following is the definition of the standard format. It @@ -144,7 +161,7 @@ def self._create # All version number strings must start with the major version. # Unlike other fields, it is not preceded by any delimiter. field(:field0) do - recognize_regexp('[0-9a-zA-Z]+', :delimiter_regexp => '', :default_delimiter => '') + recognize_number(:delimiter_regexp => '', :default_delimiter => '') end # The remainder of the version number are represented as strings @@ -154,32 +171,25 @@ def self._create # Finally, they can be optional in an unparsed string if they are # set to the default value of 0. field(:field1) do - recognize_regexp('[0-9a-zA-Z]+', :delimiter_regexp => '[^0-9a-zA-Z]+', - :default_value_optional => true) + recognize_regexp('[0-9a-zA-Z]+', :default_value_optional => true) end field(:field2) do - recognize_regexp('[0-9a-zA-Z]+', :delimiter_regexp => '[^0-9a-zA-Z]+', - :default_value_optional => true) + recognize_regexp('[0-9a-zA-Z]+', :default_value_optional => true) end field(:field3) do - recognize_regexp('[0-9a-zA-Z]+', :delimiter_regexp => '[^0-9a-zA-Z]+', - :default_value_optional => true) + recognize_regexp('[0-9a-zA-Z]+', :default_value_optional => true) end field(:field4) do - recognize_regexp('[0-9a-zA-Z]+', :delimiter_regexp => '[^0-9a-zA-Z]+', - :default_value_optional => true) + recognize_regexp('[0-9a-zA-Z]+', :default_value_optional => true) end field(:field5) do - recognize_regexp('[0-9a-zA-Z]+', :delimiter_regexp => '[^0-9a-zA-Z]+', - :default_value_optional => true) + recognize_regexp('[0-9a-zA-Z]+', :default_value_optional => true) end field(:field6) do - recognize_regexp('[0-9a-zA-Z]+', :delimiter_regexp => '[^0-9a-zA-Z]+', - :default_value_optional => true) + recognize_regexp('[0-9a-zA-Z]+', :default_value_optional => true) end field(:field7) do - recognize_regexp('[0-9a-zA-Z]+', :delimiter_regexp => '[^0-9a-zA-Z]+', - :default_value_optional => true) + recognize_regexp('[0-9a-zA-Z]+', :default_value_optional => true) end # By default, we require that at least the first two fields @@ -192,7 +202,7 @@ def self._create end - register('rubygems', Rubygems._create) unless get('rubygems') + register('rubygems', Format::Rubygems.create) unless get('rubygems') end diff --git a/lib/versionomy/formats/standard.rb b/lib/versionomy/format/standard.rb similarity index 96% rename from lib/versionomy/formats/standard.rb rename to lib/versionomy/format/standard.rb index 22da390..affd41e 100644 --- a/lib/versionomy/formats/standard.rb +++ b/lib/versionomy/format/standard.rb @@ -36,7 +36,7 @@ module Versionomy - module Formats + module Format # Get the standard format. @@ -93,13 +93,16 @@ module Formats # unparsing as well. # # For the exact annotated definition of the standard schema and format, - # see the source code for Versionomy::Formats::Standard#_create. + # see the source code for Versionomy::Format::Standard#create. def self.standard get('standard') end + # This is a namespace for the implementation of the Standard schema + # and format. + module Standard @@ -115,6 +118,15 @@ def prerelease? end + # Returns the release for this version. + # For example, converts "1.2.0a1" to "1.2.0". + # Non-prerelease versions return themselves. + + def release + self.change(:release_type => :final) + end + + end @@ -125,7 +137,7 @@ def prerelease? # contains useful examples of how to use the schema and format # definition DSLs. - def self._create + def self.create # The following is the definition of the standard schema schema_ = Schema.create do @@ -227,7 +239,7 @@ def self._create end # Add the methods in this module to each value - add_module(Formats::Standard::ExtraMethods) + add_module(Format::Standard::ExtraMethods) end # The following is the definition of the standard format. It @@ -362,7 +374,7 @@ def self._create end - register('standard', Standard._create) unless get('standard') + register('standard', Format::Standard.create) unless get('standard') end diff --git a/lib/versionomy/formats.rb b/lib/versionomy/formats.rb deleted file mode 100644 index 87db8b1..0000000 --- a/lib/versionomy/formats.rb +++ /dev/null @@ -1,93 +0,0 @@ -# ----------------------------------------------------------------------------- -# -# Versionomy format registry -# -# ----------------------------------------------------------------------------- -# Copyright 2008-2009 Daniel Azuma -# -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# * Neither the name of the copyright holder, nor the names of any other -# contributors to this software, may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# ----------------------------------------------------------------------------- -; - - -module Versionomy - - - # === Version number format regsitry. - # - # Use the methods of this module to register formats with a name. This - # allows version numbers to be serialized with their format. - # - # You may also access predefined formats such as the standard format from - # this module. It also contains the implementations of these formats as - # examples. - # - # This module also serves as a convenient namespace for implementations - # of formats. - - module Formats - - @names = ::Hash.new - - class << self - - - # Get the format with the given name. - # - # If the given name has not been defined, and strict is set to true, - # raises Versionomy::Errors::UnknownFormatError. If strict is set to - # false, returns nil if the given name has not been defined. - - def get(name_, strict_=false) - format_ = @names[name_.to_s] - if format_.nil? && strict_ - raise Errors::UnknownFormatError, name_ - end - format_ - end - - - # Register the given format under the given name. - # - # Raises Versionomy::Errors::FormatRedefinedError if the name has - # already been defined. - - def register(name_, format_) - name_ = name_.to_s - if @names.include?(name_) - raise Errors::FormatRedefinedError, name_ - end - @names[name_] = format_ - end - - - end - - end - - -end diff --git a/lib/versionomy/interface.rb b/lib/versionomy/interface.rb index c23b012..d975c0a 100644 --- a/lib/versionomy/interface.rb +++ b/lib/versionomy/interface.rb @@ -48,19 +48,19 @@ class << self # Gets the current default format. Usually this is the "standard" - # format returned by Versionomy::Formats.standard. + # format returned by Versionomy::Format.standard. def default_format - @default_format ||= Formats.standard + @default_format ||= Format.standard end # Sets the default format used by other methods of this convenience # interface. Usually, this is set to the "standard" format returned by - # Versionomy::Formats.standard and should not be changed. + # Versionomy::Format.standard and should not be changed. # # The format can be specified as a format object or the name of a format - # registered with Versionomy::Formats. If the format is set to nil, the + # registered with Versionomy::Format. If the format is set to nil, the # default_format will be reset to the "standard" format. # # Raises Versionomy::Errors::UnknownFormatError if a name is given that @@ -68,7 +68,7 @@ def default_format def default_format=(format_) if format_.kind_of?(::String) || format_.kind_of?(::Symbol) - format_ = Formats.get(format_, true) + format_ = Format.get(format_, true) end @default_format = format_ end @@ -81,7 +81,7 @@ def default_format=(format_) # array of values that will be interpreted in field order. # # The format can be specified as a format object or the name of a format - # registered with Versionomy::Formats. If the format is omitted or set + # registered with Versionomy::Format. If the format is omitted or set # to nil, the default_format will be used. # # You can also optionally provide default parameters to be used when @@ -92,7 +92,7 @@ def default_format=(format_) def create(values_=nil, format_=nil, unparse_params_=nil) if format_.kind_of?(::String) || format_.kind_of?(::Symbol) - format_ = Formats.get(format_, true) + format_ = Format.get(format_, true) end format_ ||= default_format Value.new(values_ || [], format_, unparse_params_) @@ -103,7 +103,7 @@ def create(values_=nil, format_=nil, unparse_params_=nil) # format. # # The format can be specified as a format object or the name of a format - # registered with Versionomy::Formats. If the format is omitted or set + # registered with Versionomy::Format. If the format is omitted or set # to nil, the default_format will be used. # # The parameter hash, if present, will be passed as parsing parameters @@ -116,7 +116,7 @@ def create(values_=nil, format_=nil, unparse_params_=nil) def parse(str_, format_=nil, parse_params_=nil) if format_.kind_of?(::String) || format_.kind_of?(::Symbol) - format_ = Formats.get(format_, true) + format_ = Format.get(format_, true) end format_ ||= default_format format_.parse(str_, parse_params_) diff --git a/lib/versionomy/schema/field.rb b/lib/versionomy/schema/field.rb index 2dc2c47..b34b6d4 100644 --- a/lib/versionomy/schema/field.rb +++ b/lib/versionomy/schema/field.rb @@ -127,11 +127,11 @@ def _set_compare_proc(block_) # :nodoc: def inspect # :nodoc: - to_s + "#<#{self.class}:0x#{object_id.to_s(16)} name=#{@name}>" end def to_s # :nodoc: - "#<#{self.class}:0x#{object_id.to_s(16)} name=#{@name}>" + inspect end diff --git a/lib/versionomy/schema/wrapper.rb b/lib/versionomy/schema/wrapper.rb index 7e42238..4d5abaf 100644 --- a/lib/versionomy/schema/wrapper.rb +++ b/lib/versionomy/schema/wrapper.rb @@ -78,19 +78,31 @@ def initialize(field_, modules_=[]) end + def inspect # :nodoc: + "#<#{self.class}:0x#{object_id.to_s(16)} root=#{@root_field.inspect}>" + end + + def to_s # :nodoc: + inspect + end + + # Returns true if this schema is equivalent to the other schema. # Two schemas are equivalent if their root fields are the same-- - # which means that the entire field tree is the same. + # which means that the entire field tree is the same-- and they + # include the same modules. + # Note that this is different from the definition of ==. def eql?(obj_) return false unless obj_.kind_of?(Schema::Wrapper) - return @root_field == obj_.root_field + return @root_field == obj_.root_field && @modules == obj_.modules end - # Returns true if this schema is equivalent to the other schema. + # Returns true if this schema is compatible with the other schema. # Two schemas are equivalent if their root fields are the same-- # which means that the entire field tree is the same. + # Note that this is different from the definition of eql?. def ==(obj_) eql?(obj_) @@ -110,7 +122,7 @@ def ===(obj_) def hash # :nodoc: - @hash ||= @root_field.hash + @hash ||= @root_field.hash ^ @modules.hash end diff --git a/lib/versionomy/value.rb b/lib/versionomy/value.rb index aeb1e6c..103218b 100644 --- a/lib/versionomy/value.rb +++ b/lib/versionomy/value.rb @@ -110,6 +110,28 @@ def to_s end + # Marshal this version number. + + def marshal_dump + format_name_ = Format.canonical_name_for(@format) + unless format_name_ + raise Errors::SerializationError, "Cannot marshal because the format is not registered" + end + [format_name_, @unparse_params, values_array] + end + + + # Unmarshal this version number. + + def marshal_load(data_) + format_ = Format.get(data_[0]) + unless format_ + raise Errors::SerializationError, "Cannot unmarshal because the format is not registered" + end + initialize(data_[2], format_, data_[1]) + end + + # Unparse this version number. # # Raises Versionomy::Errors::UnparseError if unparsing failed. @@ -250,14 +272,16 @@ def change(values_={}, unparse_params_={}) # be converted. def convert(format_, convert_params_=nil) - format_ = Formats.get(format_) if format_.kind_of?(::String) || format_.kind_of?(::Symbol) + if format_.kind_of?(::String) || format_.kind_of?(::Symbol) + format_ = Format.get(format_) + end return self if @format == format_ from_schema_ = @format.schema to_schema_ = format_.schema if from_schema_ == to_schema_ return Value.new(@values, format_, convert_params_) end - conversion_ = Conversions.get(from_schema_, to_schema_, true) + conversion_ = Conversion.get(from_schema_, to_schema_, true) conversion_.convert_value(self, format_, convert_params_) end @@ -269,6 +293,7 @@ def hash # :nodoc: # Returns true if this version number is equal to the given verison number. # This type of equality means the schemas and values are the same. + # Note that this is different from the definition of ==. def eql?(obj_) if obj_.kind_of?(::String) @@ -286,7 +311,8 @@ def eql?(obj_) # Returns true if this version number is equal to the given verison number. # This type of equality means that the values are the same, possibly after - # suitable conversion of the RHS. + # suitable automatic conversion of the RHS. + # Note that this is different from the definition of eql?. def ==(obj_) (self <=> obj_) == 0 @@ -337,6 +363,9 @@ def >(obj_) end + include ::Comparable + + # Field values may be retrieved by calling them as methods. def method_missing(symbol_) diff --git a/tests/tc_rubygems_basic.rb b/tests/tc_rubygems_basic.rb index 86dad6f..fcb79dd 100644 --- a/tests/tc_rubygems_basic.rb +++ b/tests/tc_rubygems_basic.rb @@ -108,18 +108,18 @@ def test_numeric_and_string_comparison # Test parsing numeric. def test_parsing_numeric - value_ = Versionomy.parse('2.0.1.1-4.6', :rubygems) + value_ = Versionomy.parse('2.0.1.1.4.6', :rubygems) assert_equal([2, 0, 1, 1, 4, 6, 0, 0], value_.values_array) - assert_equal('2.0.1.1-4.6', value_.unparse) + assert_equal('2.0.1.1.4.6', value_.unparse) end # Test parsing with a string. def test_parsing_with_string - value_ = Versionomy.parse('1.9.2 pre-2', :rubygems) + value_ = Versionomy.parse('1.9.2.pre.2', :rubygems) assert_equal([1, 9, 2, 'pre', 2, 0, 0, 0], value_.values_array) - assert_equal('1.9.2 pre-2', value_.unparse) + assert_equal('1.9.2.pre.2', value_.unparse) end @@ -154,7 +154,7 @@ def test_bump_string # Test "prerelase?" custom method - def test_prereleasep + def test_method_prereleasep value_ = Versionomy.create([1, 9, 2, 'a', 2], :rubygems) assert_equal(true, value_.prerelease?) value_ = Versionomy.create([1, 9, 2, 2], :rubygems) @@ -162,6 +162,28 @@ def test_prereleasep end + # Test "relase" custom method + + def test_method_release + value_ = Versionomy.create([1, 9, 2, 'a', 2], :rubygems) + value2_ = value_.release + assert_equal([1, 9, 2, 0, 0, 0, 0, 0], value2_.values_array) + value_ = Versionomy.create([1, 9, 2, 5, 2], :rubygems) + value2_ = value_.release + assert_equal(value_, value2_) + end + + + # Test marshalling + + def test_marshal + value_ = Versionomy.create([1, 9, 2, 'a', 2], :rubygems) + str_ = ::Marshal.dump(value_) + value2_ = ::Marshal.load(str_) + assert_equal(value_, value2_) + end + + end end diff --git a/tests/tc_rubygems_conversions.rb b/tests/tc_rubygems_conversions.rb index adfb698..0f8fd04 100644 --- a/tests/tc_rubygems_conversions.rb +++ b/tests/tc_rubygems_conversions.rb @@ -45,16 +45,22 @@ module Tests # :nodoc: class TestRubygemsConversions < Test::Unit::TestCase # :nodoc: + def setup + @standard_format = Format.get(:standard) + @rubygems_format = Format.get(:rubygems) + end + + # Test simple conversion from standard to rubygems. def test_standard_to_rubygems_simple value_ = Versionomy.parse('1.2') value2_ = value_.convert(:rubygems) - assert_equal(Formats.get(:rubygems), value2_.format) + assert_equal(@rubygems_format, value2_.format) assert_equal([1, 2, 0, 0, 0, 0, 0, 0], value2_.values_array) value_ = Versionomy.parse('1.2.4.1') value2_ = value_.convert(:rubygems) - assert_equal(Formats.get(:rubygems), value2_.format) + assert_equal(@rubygems_format, value2_.format) assert_equal([1, 2, 4, 1, 0, 0, 0, 0], value2_.values_array) end @@ -64,11 +70,15 @@ def test_standard_to_rubygems_simple def test_standard_to_rubygems_with_patchlevel value_ = Versionomy.parse('1.2-3') value2_ = value_.convert(:rubygems) - assert_equal(Formats.get(:rubygems), value2_.format) + assert_equal(@rubygems_format, value2_.format) assert_equal([1, 2, 3, 0, 0, 0, 0, 0], value2_.values_array) value_ = Versionomy.parse('1.2p3') value2_ = value_.convert(:rubygems) - assert_equal(Formats.get(:rubygems), value2_.format) + assert_equal(@rubygems_format, value2_.format) + assert_equal([1, 2, 3, 0, 0, 0, 0, 0], value2_.values_array) + value_ = Versionomy.parse('1.2c') + value2_ = value_.convert(:rubygems) + assert_equal(@rubygems_format, value2_.format) assert_equal([1, 2, 3, 0, 0, 0, 0, 0], value2_.values_array) end @@ -78,11 +88,11 @@ def test_standard_to_rubygems_with_patchlevel def test_standard_to_rubygems_beta value_ = Versionomy.parse('1.2b3') value2_ = value_.convert(:rubygems) - assert_equal(Formats.get(:rubygems), value2_.format) + assert_equal(@rubygems_format, value2_.format) assert_equal([1, 2, 'b', 3, 0, 0, 0, 0], value2_.values_array) value_ = Versionomy.parse('1.2 beta 3.4') value2_ = value_.convert(:rubygems) - assert_equal(Formats.get(:rubygems), value2_.format) + assert_equal(@rubygems_format, value2_.format) assert_equal([1, 2, 'beta', 3, 4, 0, 0, 0], value2_.values_array) end @@ -92,43 +102,29 @@ def test_standard_to_rubygems_beta def test_rubygems_to_standard_simple value_ = Versionomy.parse('1.2', :rubygems) value2_ = value_.convert(:standard) - assert_equal(Formats.get(:standard), value2_.format) + assert_equal(@standard_format, value2_.format) assert_equal([1, 2, 0, 0, :final, 0, 0], value2_.values_array) value_ = Versionomy.parse('1.2.4.1', :rubygems) value2_ = value_.convert(:standard) - assert_equal(Formats.get(:standard), value2_.format) + assert_equal(@standard_format, value2_.format) assert_equal([1, 2, 4, 1, :final, 0, 0], value2_.values_array) end - # Test conversion from rubygems to standard including a patchlevel - - def test_rubygems_to_standard_with_patchlevel - value_ = Versionomy.parse('1.2-3', :rubygems) - value2_ = value_.convert(:standard) - assert_equal(Formats.get(:standard), value2_.format) - assert_equal([1, 2, 0, 0, :final, 3, 0], value2_.values_array) - value_ = Versionomy.parse('1.2-3.4', :rubygems) - value2_ = value_.convert(:standard) - assert_equal(Formats.get(:standard), value2_.format) - assert_equal([1, 2, 0, 0, :final, 3, 4], value2_.values_array) - end - - # Test conversion from rubygems to standard with a beta version def test_rubygems_to_standard_beta value_ = Versionomy.parse('1.2.b.3', :rubygems) value2_ = value_.convert(:standard) - assert_equal(Formats.get(:standard), value2_.format) + assert_equal(@standard_format, value2_.format) assert_equal([1, 2, 0, 0, :beta, 3, 0], value2_.values_array) - value_ = Versionomy.parse('1.2-b3', :rubygems) + value_ = Versionomy.parse('1.2.b3', :rubygems) value2_ = value_.convert(:standard) - assert_equal(Formats.get(:standard), value2_.format) + assert_equal(@standard_format, value2_.format) assert_equal([1, 2, 0, 0, :beta, 3, 0], value2_.values_array) - value_ = Versionomy.parse('1.2-beta3', :rubygems) + value_ = Versionomy.parse('1.2.beta3', :rubygems) value2_ = value_.convert(:standard) - assert_equal(Formats.get(:standard), value2_.format) + assert_equal(@standard_format, value2_.format) assert_equal([1, 2, 0, 0, :beta, 3, 0], value2_.values_array) end @@ -150,7 +146,7 @@ def test_rubygems_to_standard_fail # Test equality comparisons between rubygems and standard def test_rubygems_to_standard_equality_comparison - assert_operator(Versionomy.parse('1.2-3', :rubygems), :==, Versionomy.parse('1.2p3')) + assert_operator(Versionomy.parse('1.2.0', :rubygems), :==, Versionomy.parse('1.2')) assert_operator(Versionomy.parse('1.2.b.3', :rubygems), :==, Versionomy.parse('1.2b3')) end @@ -158,7 +154,7 @@ def test_rubygems_to_standard_equality_comparison # Test inequality comparisons between rubygems and standard def test_rubygems_to_standard_equality_comparison - assert_operator(Versionomy.parse('1.2-3', :rubygems), :<, Versionomy.parse('1.2p4')) + assert_operator(Versionomy.parse('1.2.3', :rubygems), :<, Versionomy.parse('1.2.4')) assert_operator(Versionomy.parse('1.2.b.3', :rubygems), :>, Versionomy.parse('1.2b2')) assert_operator(Versionomy.parse('1.2', :rubygems), :>, Versionomy.parse('1.2b1')) end @@ -167,7 +163,7 @@ def test_rubygems_to_standard_equality_comparison # Test equality comparisons between standard and rubygems def test_standard_to_rubygems_equality_comparison - assert_operator(Versionomy.parse('1.2p3'), :==, Versionomy.parse('1.2-3', :rubygems)) + assert_operator(Versionomy.parse('1.2.0'), :==, Versionomy.parse('1.2', :rubygems)) assert_operator(Versionomy.parse('1.2b3'), :==, Versionomy.parse('1.2.beta.3', :rubygems)) end @@ -175,7 +171,7 @@ def test_standard_to_rubygems_equality_comparison # Test inequality comparisons between standard and rubygems def test_standard_to_rubygems_inequality_comparison - assert_operator(Versionomy.parse('1.2p4'), :>, Versionomy.parse('1.2-3', :rubygems)) + assert_operator(Versionomy.parse('1.2.4'), :>, Versionomy.parse('1.2.3', :rubygems)) assert_operator(Versionomy.parse('1.2b2'), :<, Versionomy.parse('1.2.beta.3', :rubygems)) assert_operator(Versionomy.parse('1.2b2'), :<, Versionomy.parse('1.2', :rubygems)) end diff --git a/tests/tc_standard_basic.rb b/tests/tc_standard_basic.rb index 4ae598e..b0e4fcf 100644 --- a/tests/tc_standard_basic.rb +++ b/tests/tc_standard_basic.rb @@ -171,7 +171,7 @@ def test_field_get_name # Test "prerelase?" custom method - def test_prereleasep + def test_method_prereleasep value_ = Versionomy.create(:major => 2, :tiny => 1, :release_type => :beta, :beta_version => 3) assert_equal(true, value_.prerelease?) value_ = Versionomy.create(:major => 2, :tiny => 1, :release_type => :final, :patchlevel => 1) @@ -181,6 +181,28 @@ def test_prereleasep end + # Test "relase" custom method + + def test_method_release + value_ = Versionomy.create(:major => 1, :minor => 9, :tiny => 2, :release_type => :alpha, :alpha_version => 4) + value2_ = value_.release + assert_equal([1, 9, 2, 0, :final, 0, 0], value2_.values_array) + value_ = Versionomy.create(:major => 1, :minor => 9, :tiny => 2) + value2_ = value_.release + assert_equal(value_, value2_) + end + + + # Test marshalling + + def test_marshal + value_ = Versionomy.create(:major => 1, :minor => 9, :tiny => 2, :release_type => :alpha, :alpha_version => 4) + str_ = ::Marshal.dump(value_) + value2_ = ::Marshal.load(str_) + assert_equal(value_, value2_) + end + + end end