loading
Generated 2024-01-10T11:54:41+01:00

All Files ( 100.0% covered at 2.61 hits/line )

10 files in total.
326 relevant lines, 326 lines covered and 0 lines missed. ( 100.0% )
File % covered Lines Relevant Lines Lines covered Lines missed Avg. Hits / Line
lib/ruby-enum.rb 100.00 % 25 11 11 0 1.00
lib/ruby-enum/enum.rb 100.00 % 174 68 68 0 5.54
lib/ruby-enum/enum/case.rb 100.00 % 84 29 29 0 5.21
lib/ruby-enum/enum/i18n_mock.rb 100.00 % 19 0 0 0 0.00
lib/ruby-enum/errors/base.rb 100.00 % 80 22 22 0 4.27
lib/ruby-enum/errors/duplicate_key_error.rb 100.00 % 14 6 6 0 1.17
lib/ruby-enum/errors/duplicate_value_error.rb 100.00 % 14 6 6 0 1.17
lib/ruby-enum/errors/uninitialized_constant_error.rb 100.00 % 13 6 6 0 1.50
spec/ruby-enum/enum_spec.rb 100.00 % 320 174 174 0 1.10
spec/ruby-enum/version_spec.rb 100.00 % 9 4 4 0 1.00

lib/ruby-enum.rb

100.0% lines covered

11 relevant lines. 11 lines covered and 0 lines missed.
    
  1. # frozen_string_literal: true
  2. 1 require 'ruby-enum/version'
  3. 1 require 'ruby-enum/enum'
  4. 1 require 'ruby-enum/enum/case'
  5. 1 require 'ruby-enum/enum/i18n_mock'
  6. # Try to load the I18n gem and provide a mock if it is not available.
  7. begin
  8. 1 require 'i18n'
  9. 1 Ruby::Enum.i18n = I18n
  10. rescue LoadError
  11. # I18n is not available
  12. skipped # :nocov:
  13. skipped # Tests for this loading are in the spec_i18n folder
  14. skipped Ruby::Enum.i18n = Ruby::Enum::I18nMock
  15. skipped # :nocov:
  16. end
  17. 1 Ruby::Enum.i18n.load_path << File.join(File.dirname(__FILE__), 'config', 'locales', 'en.yml')
  18. 1 require 'ruby-enum/errors/base'
  19. 1 require 'ruby-enum/errors/uninitialized_constant_error'
  20. 1 require 'ruby-enum/errors/duplicate_key_error'
  21. 1 require 'ruby-enum/errors/duplicate_value_error'

lib/ruby-enum/enum.rb

100.0% lines covered

68 relevant lines. 68 lines covered and 0 lines missed.
    
  1. # frozen_string_literal: true
  2. 1 module Ruby
  3. 1 module Enum
  4. 1 class << self
  5. # Needed for I18n mock
  6. 1 attr_accessor :i18n
  7. end
  8. 1 attr_reader :key, :value
  9. 1 def initialize(key, value)
  10. 11 @key = key
  11. 11 @value = value
  12. end
  13. 1 def self.included(base)
  14. 5 base.extend Enumerable
  15. 5 base.extend ClassMethods
  16. 5 base.private_class_method(:new)
  17. end
  18. 1 module ClassMethods
  19. # Define an enumerated value.
  20. #
  21. # === Parameters
  22. # [key] Enumerator key.
  23. # [value] Enumerator value.
  24. 1 def define(key, value = key)
  25. 15 @_enum_hash ||= {}
  26. 15 @_enums_by_value ||= {}
  27. 15 validate_key!(key)
  28. 13 validate_value!(value)
  29. 11 store_new_instance(key, value)
  30. 11 if upper?(key.to_s)
  31. 8 const_set key, value
  32. else
  33. 6 define_singleton_method(key) { value }
  34. end
  35. end
  36. 1 def store_new_instance(key, value)
  37. 11 new_instance = new(key, value)
  38. 11 @_enum_hash[key] = new_instance
  39. 11 @_enums_by_value[value] = new_instance
  40. end
  41. 1 def const_missing(key)
  42. 4 raise Ruby::Enum::Errors::UninitializedConstantError, name: name, key: key
  43. end
  44. # Iterate over all enumerated values.
  45. # Required for Enumerable mixin
  46. 1 def each(&block)
  47. 8 @_enum_hash.each(&block)
  48. end
  49. # Attempt to parse an enum key and return the
  50. # corresponding value.
  51. #
  52. # === Parameters
  53. # [k] The key string to parse.
  54. #
  55. # Returns the corresponding value or nil.
  56. 1 def parse(k)
  57. 4 k = k.to_s.upcase
  58. 4 each do |key, enum|
  59. 6 return enum.value if key.to_s.upcase == k
  60. end
  61. nil
  62. end
  63. # Whether the specified key exists in this enum.
  64. #
  65. # === Parameters
  66. # [k] The string key to check.
  67. #
  68. # Returns true if the key exists, false otherwise.
  69. 1 def key?(k)
  70. 7 @_enum_hash.key?(k)
  71. end
  72. # Gets the string value for the specified key.
  73. #
  74. # === Parameters
  75. # [k] The key symbol to get the value for.
  76. #
  77. # Returns the corresponding enum instance or nil.
  78. 1 def value(k)
  79. 5 enum = @_enum_hash[k]
  80. 5 enum&.value
  81. end
  82. # Whether the specified value exists in this enum.
  83. #
  84. # === Parameters
  85. # [k] The string value to check.
  86. #
  87. # Returns true if the value exists, false otherwise.
  88. 1 def value?(v)
  89. 7 @_enums_by_value.key?(v)
  90. end
  91. # Gets the key symbol for the specified value.
  92. #
  93. # === Parameters
  94. # [v] The string value to parse.
  95. #
  96. # Returns the corresponding key symbol or nil.
  97. 1 def key(v)
  98. 5 enum = @_enums_by_value[v]
  99. 5 enum&.key
  100. end
  101. # Returns all enum keys.
  102. 1 def keys
  103. 2 @_enum_hash.values.map(&:key)
  104. end
  105. # Returns all enum values.
  106. 1 def values
  107. 25 result = @_enum_hash.values.map(&:value)
  108. 25 if superclass < Ruby::Enum
  109. 3 superclass.values + result
  110. else
  111. 22 result
  112. end
  113. end
  114. # Iterate over all enumerated values.
  115. # Required for Enumerable mixin
  116. 1 def each_value(&_block)
  117. 1 @_enum_hash.each_value do |v|
  118. 2 yield v.value
  119. end
  120. end
  121. # Iterate over all enumerated keys.
  122. # Required for Enumerable mixin
  123. 1 def each_key(&_block)
  124. 1 @_enum_hash.each_value do |v|
  125. 2 yield v.key
  126. end
  127. end
  128. 1 def to_h
  129. 1 @_enum_hash.transform_values(&:value)
  130. end
  131. 1 private
  132. 1 def upper?(s)
  133. 11 !/[[:upper:]]/.match(s).nil?
  134. end
  135. 1 def validate_key!(key)
  136. 15 return unless @_enum_hash.key?(key)
  137. 2 raise Ruby::Enum::Errors::DuplicateKeyError, name: name, key: key
  138. end
  139. 1 def validate_value!(value)
  140. 13 return unless @_enums_by_value.key?(value)
  141. 2 raise Ruby::Enum::Errors::DuplicateValueError, name: name, value: value
  142. end
  143. end
  144. end
  145. end

lib/ruby-enum/enum/case.rb

100.0% lines covered

29 relevant lines. 29 lines covered and 0 lines missed.
    
  1. # frozen_string_literal: true
  2. 1 module Ruby
  3. 1 module Enum
  4. ##
  5. # Adds a method to an enum class that allows for exhaustive matching on a value.
  6. #
  7. # @example
  8. # class Color
  9. # include Ruby::Enum
  10. # include Ruby::Enum::Case
  11. #
  12. # define :RED, :red
  13. # define :GREEN, :green
  14. # define :BLUE, :blue
  15. # define :YELLOW, :yellow
  16. # end
  17. #
  18. # Color.case(Color::RED, {
  19. # [Color::RED, Color::GREEN] => -> { "red or green" },
  20. # Color::BLUE => -> { "blue" },
  21. # Color::YELLOW => -> { "yellow" },
  22. # })
  23. #
  24. # Reserves the :else key for a default case:
  25. # Color.case(Color::RED, {
  26. # [Color::RED, Color::GREEN] => -> { "red or green" },
  27. # else: -> { "blue or yellow" },
  28. # })
  29. 1 module Case
  30. 1 def self.included(klass)
  31. 1 klass.extend(ClassMethods)
  32. end
  33. ##
  34. # @see Ruby::Enum::Case
  35. 1 module ClassMethods
  36. 1 class ValuesNotDefinedError < StandardError
  37. end
  38. 1 class NotAllCasesHandledError < StandardError
  39. end
  40. 1 def case(value, cases)
  41. 9 validate_cases(cases)
  42. 7 filtered_cases = cases.select do |values, _proc|
  43. 15 values = [values] unless values.is_a?(Array)
  44. 15 values.include?(value)
  45. end
  46. 7 return call_proc(cases[:else], value) if filtered_cases.none?
  47. 9 results = filtered_cases.map { |_values, proc| call_proc(proc, value) }
  48. # Return the first result if there is only one result
  49. 4 results.size == 1 ? results.first : results
  50. end
  51. 1 private
  52. 1 def call_proc(proc, value)
  53. 8 return if proc.nil?
  54. 6 if proc.arity == 1
  55. 1 proc.call(value)
  56. else
  57. 5 proc.call
  58. end
  59. end
  60. 1 def validate_cases(cases)
  61. 9 all_values = cases.keys.flatten - [:else]
  62. 9 else_defined = cases.key?(:else)
  63. 9 superfluous_values = all_values - values
  64. 9 missing_values = values - all_values
  65. 9 raise ValuesNotDefinedError, "Value(s) not defined: #{superfluous_values.join(', ')}" if superfluous_values.any?
  66. 8 raise NotAllCasesHandledError, "Not all cases handled: #{missing_values.join(', ')}" if missing_values.any? && !else_defined
  67. end
  68. end
  69. end
  70. end
  71. end

lib/ruby-enum/enum/i18n_mock.rb

100.0% lines covered

0 relevant lines. 0 lines covered and 0 lines missed.
    
  1. # frozen_string_literal: true
  2. skipped # :nocov:
  3. skipped module Ruby
  4. skipped module Enum
  5. skipped ##
  6. skipped # Mock I18n module in case the i18n gem is not available.
  7. skipped module I18nMock
  8. skipped def self.load_path
  9. skipped []
  10. skipped end
  11. skipped
  12. skipped def self.translate(key, _options = {})
  13. skipped key
  14. skipped end
  15. skipped end
  16. skipped end
  17. skipped end
  18. skipped # :nocov:

lib/ruby-enum/errors/base.rb

100.0% lines covered

22 relevant lines. 22 lines covered and 0 lines missed.
    
  1. # frozen_string_literal: true
  2. 1 module Ruby
  3. 1 module Enum
  4. 1 module Errors
  5. 1 class Base < StandardError
  6. # Problem occurred.
  7. 1 attr_reader :problem
  8. # Summary of the problem.
  9. 1 attr_reader :summary
  10. # Suggested problem resolution.
  11. 1 attr_reader :resolution
  12. # Compose the message.
  13. # === Parameters
  14. # [key] Lookup key in the translation table.
  15. # [attributes] The objects to pass to create the message.
  16. 1 def compose_message(key, attributes = {})
  17. 8 @problem = create_problem(key, attributes)
  18. 8 @summary = create_summary(key, attributes)
  19. 8 @resolution = create_resolution(key, attributes)
  20. 8 "\nProblem:\n #{@problem}" \
  21. "\nSummary:\n #{@summary}" + "\nResolution:\n #{@resolution}"
  22. end
  23. 1 private
  24. 1 BASE_KEY = 'ruby.enum.errors.messages' # :nodoc:
  25. # Given the key of the specific error and the options hash, translate the
  26. # message.
  27. #
  28. # === Parameters
  29. # [key] The key of the error in the locales.
  30. # [options] The objects to pass to create the message.
  31. #
  32. # Returns a localized error message string.
  33. 1 def translate(key, options)
  34. 24 Ruby::Enum.i18n.translate("#{BASE_KEY}.#{key}", locale: :en, **options).strip
  35. end
  36. # Create the problem.
  37. #
  38. # === Parameters
  39. # [key] The error key.
  40. # [attributes] The attributes to interpolate.
  41. #
  42. # Returns the problem.
  43. 1 def create_problem(key, attributes)
  44. 8 translate("#{key}.message", attributes)
  45. end
  46. # Create the summary.
  47. #
  48. # === Parameters
  49. # [key] The error key.
  50. # [attributes] The attributes to interpolate.
  51. #
  52. # Returns the summary.
  53. 1 def create_summary(key, attributes)
  54. 8 translate("#{key}.summary", attributes)
  55. end
  56. # Create the resolution.
  57. #
  58. # === Parameters
  59. # [key] The error key.
  60. # [attributes] The attributes to interpolate.
  61. #
  62. # Returns the resolution.
  63. 1 def create_resolution(key, attributes)
  64. 8 translate("#{key}.resolution", attributes)
  65. end
  66. end
  67. end
  68. end
  69. end

lib/ruby-enum/errors/duplicate_key_error.rb

100.0% lines covered

6 relevant lines. 6 lines covered and 0 lines missed.
    
  1. # frozen_string_literal: true
  2. 1 module Ruby
  3. 1 module Enum
  4. 1 module Errors
  5. # Error raised when a duplicate enum key is found
  6. 1 class DuplicateKeyError < Base
  7. 1 def initialize(attrs)
  8. 2 super(compose_message('duplicate_key', attrs))
  9. end
  10. end
  11. end
  12. end
  13. end

lib/ruby-enum/errors/duplicate_value_error.rb

100.0% lines covered

6 relevant lines. 6 lines covered and 0 lines missed.
    
  1. # frozen_string_literal: true
  2. 1 module Ruby
  3. 1 module Enum
  4. 1 module Errors
  5. # Error raised when a duplicate enum value is found
  6. 1 class DuplicateValueError < Base
  7. 1 def initialize(attrs)
  8. 2 super(compose_message('duplicate_value', attrs))
  9. end
  10. end
  11. end
  12. end
  13. end

lib/ruby-enum/errors/uninitialized_constant_error.rb

100.0% lines covered

6 relevant lines. 6 lines covered and 0 lines missed.
    
  1. # frozen_string_literal: true
  2. 1 module Ruby
  3. 1 module Enum
  4. 1 module Errors
  5. 1 class UninitializedConstantError < Base
  6. 1 def initialize(attrs)
  7. 4 super(compose_message('uninitialized_constant', attrs))
  8. end
  9. end
  10. end
  11. end
  12. end

spec/ruby-enum/enum_spec.rb

100.0% lines covered

174 relevant lines. 174 lines covered and 0 lines missed.
    
  1. # frozen_string_literal: true
  2. 1 require 'spec_helper'
  3. 1 class Colors
  4. 1 include Ruby::Enum
  5. 1 define :RED, 'red'
  6. 1 define :GREEN, 'green'
  7. end
  8. 1 class FirstSubclass < Colors
  9. 1 define :ORANGE, 'orange'
  10. end
  11. 1 class SecondSubclass < FirstSubclass
  12. 1 define :PINK, 'pink'
  13. end
  14. 1 describe Ruby::Enum do
  15. 1 it 'returns an enum value' do
  16. 1 expect(Colors::RED).to eq 'red'
  17. 1 expect(Colors::GREEN).to eq 'green'
  18. end
  19. 1 context 'when the i18n gem is loaded' do
  20. 1 it 'raises UninitializedConstantError on an invalid constant' do
  21. 1 expect do
  22. 1 Colors::ANYTHING
  23. end.to raise_error Ruby::Enum::Errors::UninitializedConstantError, /The constant Colors::ANYTHING has not been defined./
  24. end
  25. end
  26. 1 context 'when the i18n gem is not loaded' do
  27. 1 before do
  28. 1 allow(described_class).to receive(:i18n).and_return(Ruby::Enum::I18nMock)
  29. end
  30. 1 it 'raises UninitializedConstantError on an invalid constant' do
  31. 1 expect do
  32. 1 Colors::ANYTHING
  33. end.to raise_error Ruby::Enum::Errors::UninitializedConstantError, /ruby.enum.errors.messages.uninitialized_constant.summary/
  34. end
  35. end
  36. 1 describe '#each' do
  37. 1 it 'iterates over constants' do
  38. 1 keys = []
  39. 1 enum_keys = []
  40. 1 enum_values = []
  41. 1 Colors.each do |key, enum|
  42. 2 keys << key
  43. 2 enum_keys << enum.key
  44. 2 enum_values << enum.value
  45. end
  46. 1 expect(keys).to eq %i[RED GREEN]
  47. 1 expect(enum_keys).to eq %i[RED GREEN]
  48. 1 expect(enum_values).to eq %w[red green]
  49. end
  50. end
  51. 1 describe '#map' do
  52. 1 it 'maps constants' do
  53. 1 key_key_values = Colors.map do |key, enum|
  54. 2 [key, enum.key, enum.value]
  55. end
  56. 1 expect(key_key_values.count).to eq 2
  57. 1 expect(key_key_values[0]).to eq [:RED, :RED, 'red']
  58. 1 expect(key_key_values[1]).to eq [:GREEN, :GREEN, 'green']
  59. end
  60. end
  61. 1 describe '#parse' do
  62. 1 it 'parses exact value' do
  63. 1 expect(Colors.parse('red')).to eq(Colors::RED)
  64. end
  65. 1 it 'is case-insensitive' do
  66. 1 expect(Colors.parse('ReD')).to eq(Colors::RED)
  67. end
  68. 1 it 'returns nil for a null value' do
  69. 1 expect(Colors.parse(nil)).to be_nil
  70. end
  71. 1 it 'returns nil for an invalid value' do
  72. 1 expect(Colors.parse('invalid')).to be_nil
  73. end
  74. end
  75. 1 describe '#key?' do
  76. 1 it 'returns true for valid keys accessed directly' do
  77. 1 Colors.keys.each do |key| # rubocop:disable Style/HashEachMethods
  78. 2 expect(Colors.key?(key)).to be(true)
  79. end
  80. end
  81. 1 it 'returns true for valid keys accessed via each_keys' do
  82. 1 Colors.each_key do |key|
  83. 2 expect(Colors.key?(key)).to be(true)
  84. end
  85. end
  86. 1 it 'returns false for invalid keys' do
  87. 1 expect(Colors.key?(:NOT_A_KEY)).to be(false)
  88. end
  89. end
  90. 1 describe '#value' do
  91. 1 it 'returns string values for keys' do
  92. 1 Colors.each do |key, enum|
  93. 2 expect(Colors.value(key)).to eq(enum.value)
  94. end
  95. end
  96. 1 it 'returns nil for an invalid key' do
  97. 1 expect(Colors.value(:NOT_A_KEY)).to be_nil
  98. end
  99. end
  100. 1 describe '#value?' do
  101. 1 it 'returns true for valid values accessed directly' do
  102. 1 Colors.values.each do |value| # rubocop:disable Style/HashEachMethods
  103. 2 expect(Colors.value?(value)).to be(true)
  104. end
  105. end
  106. 1 it 'returns true for valid values accessed via each_value' do
  107. 1 Colors.each_value do |value|
  108. 2 expect(Colors.value?(value)).to be(true)
  109. end
  110. end
  111. 1 it 'returns false for invalid values' do
  112. 1 expect(Colors.value?('I am not a value')).to be(false)
  113. end
  114. end
  115. 1 describe '#key' do
  116. 1 it 'returns enum instances for values' do
  117. 1 Colors.each do |_, enum| # rubocop:disable Style/HashEachMethods
  118. 2 expect(Colors.key(enum.value)).to eq(enum.key)
  119. end
  120. end
  121. 1 it 'returns nil for an invalid value' do
  122. 1 expect(Colors.key('invalid')).to be_nil
  123. end
  124. end
  125. 1 describe '#keys' do
  126. 1 it 'returns keys' do
  127. 1 expect(Colors.keys).to eq(%i[RED GREEN])
  128. end
  129. end
  130. 1 describe '#values' do
  131. 1 it 'returns values' do
  132. 1 expect(Colors.values).to eq(%w[red green])
  133. end
  134. end
  135. 1 describe '#to_h' do
  136. 1 it 'returns a hash of key:values' do
  137. 1 expect(Colors.to_h).to eq(RED: 'red', GREEN: 'green')
  138. end
  139. end
  140. 1 context 'when a duplicate key is used' do
  141. 1 context 'when the i18n gem is loaded' do
  142. 1 it 'raises DuplicateKeyError' do
  143. 1 expect do
  144. 1 Colors.class_eval do
  145. 1 define :RED, 'some'
  146. end
  147. end.to raise_error Ruby::Enum::Errors::DuplicateKeyError, /The constant Colors::RED has already been defined./
  148. end
  149. end
  150. 1 context 'when the i18n gem is not loaded' do
  151. 1 before do
  152. 1 allow(described_class).to receive(:i18n).and_return(Ruby::Enum::I18nMock)
  153. end
  154. 1 it 'raises DuplicateKeyError' do
  155. 1 expect do
  156. 1 Colors.class_eval do
  157. 1 define :RED, 'some'
  158. end
  159. end.to raise_error Ruby::Enum::Errors::DuplicateKeyError, /ruby.enum.errors.messages.duplicate_key.message/
  160. end
  161. end
  162. end
  163. 1 context 'when a duplicate value is used' do
  164. 1 context 'when the i18n gem is loaded' do
  165. 1 it 'raises a DuplicateValueError' do
  166. 1 expect do
  167. 1 Colors.class_eval do
  168. 1 define :Other, 'red'
  169. end
  170. end.to raise_error Ruby::Enum::Errors::DuplicateValueError, /The value red has already been defined./
  171. end
  172. end
  173. 1 context 'when the i18n gem is not loaded' do
  174. 1 before do
  175. 1 allow(described_class).to receive(:i18n).and_return(Ruby::Enum::I18nMock)
  176. end
  177. 1 it 'raises a DuplicateValueError' do
  178. 1 expect do
  179. 1 Colors.class_eval do
  180. 1 define :Other, 'red'
  181. end
  182. end.to raise_error Ruby::Enum::Errors::DuplicateValueError, /ruby.enum.errors.messages.duplicate_value.summary/
  183. end
  184. end
  185. end
  186. 1 describe 'Given a class that has not defined any enums' do
  187. 1 class EmptyEnums
  188. 1 include Ruby::Enum
  189. end
  190. 1 it do
  191. 2 expect { EmptyEnums::ORANGE }.to raise_error Ruby::Enum::Errors::UninitializedConstantError
  192. end
  193. end
  194. 1 context 'when a constant is redefined in a global namespace' do
  195. 1 before do
  196. 1 RED = 'black'
  197. end
  198. 2 it { expect(Colors::RED).to eq 'red' }
  199. end
  200. 1 describe 'Subclass behavior' do
  201. 1 it 'contains the enums defined in the parent class' do
  202. 1 expect(FirstSubclass::GREEN).to eq 'green'
  203. 1 expect(FirstSubclass::RED).to eq 'red'
  204. end
  205. 1 it 'contains its own enums' do
  206. 1 expect(FirstSubclass::ORANGE).to eq 'orange'
  207. end
  208. 1 it 'parent class should not have enums defined in child classes' do
  209. 2 expect { Colors::ORANGE }.to raise_error Ruby::Enum::Errors::UninitializedConstantError
  210. end
  211. 1 context 'when defining a 2 level depth subclass' do
  212. 2 subject { SecondSubclass }
  213. 1 it 'contains its own enums and all the enums defined in the parent classes' do
  214. 1 expect(subject::RED).to eq 'red'
  215. 1 expect(subject::GREEN).to eq 'green'
  216. 1 expect(subject::ORANGE).to eq 'orange'
  217. 1 expect(subject::PINK).to eq 'pink'
  218. end
  219. 1 describe '#values' do
  220. 2 subject { SecondSubclass.values }
  221. 1 it 'contains the values from all of the parent classes' do
  222. 1 expect(subject).to eq(%w[red green orange pink])
  223. end
  224. end
  225. end
  226. 1 describe '#values' do
  227. 2 subject { FirstSubclass.values }
  228. 1 it 'contains the values from the parent class' do
  229. 1 expect(subject).to eq(%w[red green orange])
  230. end
  231. end
  232. end
  233. 1 describe 'default value' do
  234. 1 class Default
  235. 1 include Ruby::Enum
  236. 1 define :KEY
  237. end
  238. 2 subject { Default::KEY }
  239. 1 it 'equals the key' do
  240. 1 expect(subject).to eq(:KEY)
  241. end
  242. end
  243. 1 describe 'non constant definitions' do
  244. 1 class States
  245. 1 include Ruby::Enum
  246. 1 define :created, 'Created'
  247. 1 define :published, 'Published'
  248. 1 define :undefined
  249. end
  250. 2 subject { States }
  251. 1 it 'behaves like an enum' do
  252. 1 expect(subject.created).to eq 'Created'
  253. 1 expect(subject.published).to eq 'Published'
  254. 1 expect(subject.undefined).to eq :undefined
  255. 1 expect(subject.key?(:created)).to be true
  256. 1 expect(subject.key('Created')).to eq :created
  257. 1 expect(subject.value?('Created')).to be true
  258. 1 expect(subject.value(:created)).to eq 'Created'
  259. 1 expect(subject.key?(:undefined)).to be true
  260. 1 expect(subject.key(:undefined)).to eq :undefined
  261. 1 expect(subject.value?(:undefined)).to be true
  262. 1 expect(subject.value(:undefined)).to eq :undefined
  263. end
  264. end
  265. end

spec/ruby-enum/version_spec.rb

100.0% lines covered

4 relevant lines. 4 lines covered and 0 lines missed.
    
  1. # frozen_string_literal: true
  2. 1 require 'spec_helper'
  3. 1 describe Ruby::Enum do
  4. 1 it 'has a version' do
  5. 1 expect(Ruby::Enum::VERSION).not_to be_nil
  6. end
  7. end