loading
Generated 2026-07-05T18:35:44+00:00

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

12 files in total.
176 relevant lines, 176 lines covered and 0 lines missed. ( 100.0% )
12 total branches, 12 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 % 20 14 14 0 1.00 100.00 % 0 0 0
lib/xdg/cache.rb 100.00 % 27 13 13 0 3.77 100.00 % 0 0 0
lib/xdg/config.rb 100.00 % 28 14 14 0 3.57 100.00 % 0 0 0
lib/xdg/data.rb 100.00 % 28 14 14 0 3.57 100.00 % 0 0 0
lib/xdg/environment.rb 100.00 % 39 21 21 0 4.14 100.00 % 0 0 0
lib/xdg/pair.rb 100.00 % 27 13 13 0 16.69 100.00 % 4 4 0
lib/xdg/paths/any.rb 100.00 % 36 18 18 0 52.44 100.00 % 4 4 0
lib/xdg/paths/combined.rb 100.00 % 30 15 15 0 22.00 100.00 % 0 0 0
lib/xdg/paths/directory.rb 100.00 % 34 16 16 0 13.13 100.00 % 4 4 0
lib/xdg/paths/home.rb 100.00 % 25 12 12 0 17.83 100.00 % 0 0 0
lib/xdg/runtime.rb 100.00 % 27 13 13 0 3.77 100.00 % 0 0 0
lib/xdg/state.rb 100.00 % 27 13 13 0 3.77 100.00 % 0 0 0

lib/xdg.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 "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/any"
  8. 1 require "xdg/paths/combined"
  9. 1 require "xdg/paths/directory"
  10. 1 require "xdg/paths/home"
  11. 1 require "xdg/runtime"
  12. 1 require "xdg/state"
  13. # Main namespace.
  14. 1 module XDG
  15. 1 DELIMITER = "="
  16. 1 def self.new = Environment.new
  17. 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. 19 @combined = Paths::Combined.new home.new(HOME_PAIR, environment),
  12. directories.new(Pair.new, environment)
  13. 19 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. 19 @combined = Paths::Combined.new home.new(HOME_PAIR, environment),
  13. directories.new(DIRS_PAIR, environment)
  14. 19 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. 19 @combined = Paths::Combined.new home.new(HOME_PAIR, environment),
  13. directories.new(DIRS_PAIR, environment)
  14. 19 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

21 relevant lines. 21 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. 12 @cache = Cache.new(home:, directories:, environment:)
  7. 12 @config = Config.new(home:, directories:, environment:)
  8. 12 @data = Data.new(home:, directories:, environment:)
  9. 12 @runtime = Runtime.new(environment:)
  10. 12 @state = State.new(home:, directories:, environment:)
  11. 12 freeze
  12. end
  13. 1 def cache_home = cache.home
  14. 1 def config_home = config.home
  15. 1 def config_dirs = config.directories
  16. 1 def data_home = data.home
  17. 1 def data_dirs = data.directories
  18. 1 def runtime_dir = runtime.home
  19. 1 def state_home = state.home
  20. 1 def to_s = "#{cache} #{config} #{data} #{runtime} #{state}"
  21. 1 alias to_str to_s
  22. 1 def inspect = "#<#{self.class}:#{object_id} #{self}>"
  23. 1 private
  24. 1 attr_reader :cache, :config, :data, :runtime, :state
  25. end
  26. 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. 187 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/any.rb

100.0% lines covered

100.0% branches covered

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

lib/xdg/paths/combined.rb

100.0% lines covered

100.0% branches covered

15 relevant lines. 15 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. 1 module Paths
  4. # The combined home and directory paths.
  5. 1 class Combined
  6. 1 def initialize initial_home, initial_directories
  7. 106 @initial_home = initial_home
  8. 106 @initial_directories = initial_directories
  9. 106 freeze
  10. end
  11. 1 def home = initial_home.dynamic
  12. 1 def directories = initial_directories.dynamic
  13. 1 def all = directories.prepend(*home)
  14. 1 def to_s = [initial_home.to_s, initial_directories.to_s].reject(&:empty?).join " "
  15. 1 alias to_str to_s
  16. 1 def inspect = "#<#{self.class}:#{object_id} #{self}>"
  17. 1 private
  18. 1 attr_reader :initial_home, :initial_directories
  19. end
  20. end
  21. end

lib/xdg/paths/directory.rb

100.0% lines covered

100.0% branches covered

16 relevant lines. 16 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. 1 module Paths
  4. # A collection of XDG directories.
  5. 1 class Directory < Any
  6. 1 DELIMITER = ":"
  7. 6 def default = value.split(DELIMITER).map { |path| expand path }
  8. 1 def dynamic
  9. 130 then: 53 else: 12 String(environment[key]).then { |env_value| env_value.empty? ? value : env_value }
  10. .split(DELIMITER)
  11. .uniq
  12. 58 .map { |path| expand path }
  13. end
  14. 1 def to_s = [key, dynamic.join(DELIMITER)].reject(&:empty?).join XDG::DELIMITER
  15. 1 alias to_str to_s
  16. 1 def inspect
  17. 2 pairs = to_s
  18. 2 type = self.class
  19. 2 then: 1 else: 1 pairs.empty? ? "#<#{type}:#{object_id}>" : "#<#{type}:#{object_id} #{self}>"
  20. end
  21. 1 def key = String pair.key
  22. 1 def value = String pair.value
  23. end
  24. end
  25. end

lib/xdg/paths/home.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 module XDG
  3. 1 module Paths
  4. # A XDG home path.
  5. 1 class Home < Any
  6. 1 KEY = "HOME"
  7. 1 def initialize pair, environment = ENV, default_key: KEY
  8. 102 @default_key = default_key
  9. 102 super(pair, environment)
  10. end
  11. 1 protected
  12. 1 def expand(path) = home.join(path).expand_path
  13. 1 def home = Pathname environment.fetch(default_key)
  14. 1 private
  15. 1 attr_reader :default_key
  16. end
  17. end
  18. end

lib/xdg/runtime.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 runtime support.
  6. 1 class Runtime
  7. 1 extend Forwardable
  8. 1 HOME_PAIR = Pair["XDG_RUNTIME_DIR", nil].freeze
  9. 1 delegate %i[home directories all to_s to_str] => :combined
  10. 1 def initialize home: Paths::Any, directories: Paths::Directory, environment: ENV
  11. 19 @combined = Paths::Combined.new home.new(HOME_PAIR, environment),
  12. directories.new(Pair.new, environment)
  13. 19 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/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. 19 @combined = Paths::Combined.new home.new(HOME_PAIR, environment),
  12. directories.new(Pair.new, environment)
  13. 19 freeze
  14. end
  15. 1 def inspect = "#<#{self.class}:#{object_id} #{self}>"
  16. 1 private
  17. 1 attr_reader :combined
  18. end
  19. end