loading
Generated 2025-10-09T00:04:24+00:00

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

10 files in total.
159 relevant lines, 159 lines covered and 0 lines missed. ( 100.0% )
10 total branches, 10 branches covered and 0 branches missed. ( 100.0% )
File % covered Lines Relevant Lines Lines covered Lines missed Avg. Hits / Line Branch Coverage Branches Covered branches Missed branches
lib/xdg.rb 100.00 % 18 12 12 0 1.00 100.00 % 0 0 0
lib/xdg/cache.rb 100.00 % 27 13 13 0 3.62 100.00 % 0 0 0
lib/xdg/config.rb 100.00 % 28 14 14 0 3.43 100.00 % 0 0 0
lib/xdg/data.rb 100.00 % 28 14 14 0 3.43 100.00 % 0 0 0
lib/xdg/environment.rb 100.00 % 36 19 19 0 3.63 100.00 % 0 0 0
lib/xdg/pair.rb 100.00 % 27 13 13 0 14.00 100.00 % 4 4 0
lib/xdg/paths/combined.rb 100.00 % 32 16 16 0 16.38 100.00 % 0 0 0
lib/xdg/paths/directory.rb 100.00 % 48 24 24 0 20.92 100.00 % 4 4 0
lib/xdg/paths/home.rb 100.00 % 41 21 21 0 17.43 100.00 % 2 2 0
lib/xdg/state.rb 100.00 % 27 13 13 0 3.62 100.00 % 0 0 0

lib/xdg.rb

100.0% lines covered

100.0% branches covered

12 relevant lines. 12 lines covered and 0 lines missed.
0 total branches, 0 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 require "xdg/cache"
  3. 1 require "xdg/config"
  4. 1 require "xdg/data"
  5. 1 require "xdg/environment"
  6. 1 require "xdg/pair"
  7. 1 require "xdg/paths/combined"
  8. 1 require "xdg/paths/directory"
  9. 1 require "xdg/paths/home"
  10. 1 require "xdg/state"
  11. # Main namespace.
  12. 1 module XDG
  13. 1 DELIMITER = "="
  14. 1 def self.new = Environment.new
  15. end

lib/xdg/cache.rb

100.0% lines covered

100.0% branches covered

13 relevant lines. 13 lines covered and 0 lines missed.
0 total branches, 0 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 require "forwardable"
  3. 1 require "xdg/pair"
  4. 1 module XDG
  5. # Provides cache support.
  6. 1 class Cache
  7. 1 extend Forwardable
  8. 1 HOME_PAIR = Pair["XDG_CACHE_HOME", ".cache"].freeze
  9. 1 delegate %i[home directories all to_s to_str] => :combined
  10. 1 def initialize home: Paths::Home, directories: Paths::Directory, environment: ENV
  11. 18 @combined = Paths::Combined.new home.new(HOME_PAIR, environment),
  12. directories.new(Pair.new, environment)
  13. 18 freeze
  14. end
  15. 1 def inspect = "#<#{self.class}:#{object_id} #{self}>"
  16. 1 private
  17. 1 attr_reader :combined
  18. end
  19. end

lib/xdg/config.rb

100.0% lines covered

100.0% branches covered

14 relevant lines. 14 lines covered and 0 lines missed.
0 total branches, 0 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 require "forwardable"
  3. 1 require "xdg/pair"
  4. 1 module XDG
  5. # Provides configuration support.
  6. 1 class Config
  7. 1 extend Forwardable
  8. 1 HOME_PAIR = Pair["XDG_CONFIG_HOME", ".config"].freeze
  9. 1 DIRS_PAIR = Pair["XDG_CONFIG_DIRS", "/etc/xdg"].freeze
  10. 1 delegate %i[home directories all to_s to_str] => :combined
  11. 1 def initialize home: Paths::Home, directories: Paths::Directory, environment: ENV
  12. 18 @combined = Paths::Combined.new home.new(HOME_PAIR, environment),
  13. directories.new(DIRS_PAIR, environment)
  14. 18 freeze
  15. end
  16. 1 def inspect = "#<#{self.class}:#{object_id} #{self}>"
  17. 1 private
  18. 1 attr_reader :combined
  19. end
  20. end

lib/xdg/data.rb

100.0% lines covered

100.0% branches covered

14 relevant lines. 14 lines covered and 0 lines missed.
0 total branches, 0 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 require "forwardable"
  3. 1 require "xdg/pair"
  4. 1 module XDG
  5. # Provides data support.
  6. 1 class Data
  7. 1 extend Forwardable
  8. 1 HOME_PAIR = Pair["XDG_DATA_HOME", ".local/share"].freeze
  9. 1 DIRS_PAIR = Pair["XDG_DATA_DIRS", "/usr/local/share:/usr/share"].freeze
  10. 1 delegate %i[home directories all to_s to_str] => :combined
  11. 1 def initialize home: Paths::Home, directories: Paths::Directory, environment: ENV
  12. 18 @combined = Paths::Combined.new home.new(HOME_PAIR, environment),
  13. directories.new(DIRS_PAIR, environment)
  14. 18 freeze
  15. end
  16. 1 def inspect = "#<#{self.class}:#{object_id} #{self}>"
  17. 1 private
  18. 1 attr_reader :combined
  19. end
  20. end

lib/xdg/environment.rb

100.0% lines covered

100.0% branches covered

19 relevant lines. 19 lines covered and 0 lines missed.
0 total branches, 0 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 module XDG
  3. # A convenience wrapper to all XDG functionality.
  4. 1 class Environment
  5. 1 def initialize home: Paths::Home, directories: Paths::Directory, environment: ENV
  6. 11 @cache = Cache.new(home:, directories:, environment:)
  7. 11 @config = Config.new(home:, directories:, environment:)
  8. 11 @data = Data.new(home:, directories:, environment:)
  9. 11 @state = State.new(home:, directories:, environment:)
  10. 11 freeze
  11. end
  12. 1 def cache_home = cache.home
  13. 1 def config_home = config.home
  14. 1 def config_dirs = config.directories
  15. 1 def data_home = data.home
  16. 1 def data_dirs = data.directories
  17. 1 def state_home = state.home
  18. 1 def to_s = "#{cache} #{config} #{data} #{state}"
  19. 1 alias to_str to_s
  20. 1 def inspect = "#<#{self.class}:#{object_id} #{self}>"
  21. 1 private
  22. 1 attr_reader :cache, :config, :data, :state
  23. end
  24. end

lib/xdg/pair.rb

100.0% lines covered

100.0% branches covered

13 relevant lines. 13 lines covered and 0 lines missed.
4 total branches, 4 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 module XDG
  3. # A generic key-value pair (KVP).
  4. 1 Pair = Data.define :key, :value do
  5. 1 def initialize key: nil, value: nil
  6. 152 super
  7. end
  8. 1 def key? = key.to_s.size.positive?
  9. 1 def value? = value.to_s.size.positive?
  10. 5 def empty? = !(key? && value?)
  11. 1 def to_env = {key => value}
  12. 9 then: 6 else: 2 def to_s = key? || value? ? "#{key}#{DELIMITER}#{value}" : ""
  13. 1 alias_method :to_str, :to_s
  14. 1 def inspect
  15. 4 type = self.class
  16. 4 then: 3 else: 1 key? || value? ? "#<data #{type} #{key}#{DELIMITER}#{value}>" : "#<data #{type}>"
  17. end
  18. end
  19. end

lib/xdg/paths/combined.rb

100.0% lines covered

100.0% branches covered

16 relevant lines. 16 lines covered and 0 lines missed.
0 total branches, 0 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 require "pathname"
  3. 1 module XDG
  4. 1 module Paths
  5. # The combined home and directory paths.
  6. 1 class Combined
  7. 1 def initialize initial_home, initial_directories
  8. 83 @initial_home = initial_home
  9. 83 @initial_directories = initial_directories
  10. 83 freeze
  11. end
  12. 1 def home = initial_home.dynamic
  13. 1 def directories = initial_directories.dynamic
  14. 1 def all = directories.prepend(*home)
  15. 1 def to_s = [initial_home.to_s, initial_directories.to_s].reject(&:empty?).join " "
  16. 1 alias to_str to_s
  17. 1 def inspect = "#<#{self.class}:#{object_id} #{self}>"
  18. 1 private
  19. 1 attr_reader :initial_home, :initial_directories
  20. end
  21. end
  22. end

lib/xdg/paths/directory.rb

100.0% lines covered

100.0% branches covered

24 relevant lines. 24 lines covered and 0 lines missed.
4 total branches, 4 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 require "pathname"
  3. 1 module XDG
  4. 1 module Paths
  5. # A collection of XDG directories.
  6. 1 class Directory
  7. 1 DELIMITER = ":"
  8. 1 def initialize pair, environment = ENV
  9. 101 @pair = pair
  10. 101 @environment = environment
  11. 101 freeze
  12. end
  13. 6 def default = value.split(DELIMITER).map { |path| expand path }
  14. 1 def dynamic
  15. 114 then: 45 else: 12 String(environment[key]).then { |env_value| env_value.empty? ? value : env_value }
  16. .split(DELIMITER)
  17. .uniq
  18. 58 .map { |path| expand path }
  19. end
  20. 1 def to_s = [key, dynamic.join(DELIMITER)].reject(&:empty?).join XDG::DELIMITER
  21. 1 alias to_str to_s
  22. 1 def inspect
  23. 2 pairs = to_s
  24. 2 type = self.class
  25. 2 then: 1 else: 1 pairs.empty? ? "#<#{type}:#{object_id}>" : "#<#{type}:#{object_id} #{self}>"
  26. end
  27. 1 private
  28. 1 attr_reader :pair, :environment
  29. 1 def key = String pair.key
  30. 1 def value = String pair.value
  31. 1 def expand(path) = Pathname(path).expand_path
  32. end
  33. end
  34. end

lib/xdg/paths/home.rb

100.0% lines covered

100.0% branches covered

21 relevant lines. 21 lines covered and 0 lines missed.
2 total branches, 2 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 require "forwardable"
  3. 1 require "pathname"
  4. 1 module XDG
  5. 1 module Paths
  6. # A XDG home path.
  7. 1 class Home
  8. 1 extend Forwardable
  9. 1 KEY = "HOME"
  10. 1 delegate %i[key value] => :pair
  11. 1 def initialize pair, environment = ENV
  12. 98 @pair = pair
  13. 98 @environment = environment
  14. 98 freeze
  15. end
  16. 1 def default = expand String(value)
  17. 55 then: 31 else: 23 def dynamic = String(environment[key]).then { |path| path.empty? ? default : expand(path) }
  18. 1 def to_s = [pair.key, dynamic].compact.join XDG::DELIMITER
  19. 1 alias to_str to_s
  20. 1 def inspect = "#<#{self.class}:#{object_id} #{self}>"
  21. 1 private
  22. 1 attr_reader :pair, :environment
  23. 1 def expand(path) = home.join(path).expand_path
  24. 1 def home = Pathname environment.fetch(KEY)
  25. end
  26. end
  27. end

lib/xdg/state.rb

100.0% lines covered

100.0% branches covered

13 relevant lines. 13 lines covered and 0 lines missed.
0 total branches, 0 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 require "forwardable"
  3. 1 require "xdg/pair"
  4. 1 module XDG
  5. # Provides state support.
  6. 1 class State
  7. 1 extend Forwardable
  8. 1 HOME_PAIR = Pair["XDG_STATE_HOME", ".local/state"].freeze
  9. 1 delegate %i[home directories all to_s to_str] => :combined
  10. 1 def initialize home: Paths::Home, directories: Paths::Directory, environment: ENV
  11. 18 @combined = Paths::Combined.new home.new(HOME_PAIR, environment),
  12. directories.new(Pair.new, environment)
  13. 18 freeze
  14. end
  15. 1 def inspect = "#<#{self.class}:#{object_id} #{self}>"
  16. 1 private
  17. 1 attr_reader :combined
  18. end
  19. end