loading
Generated 2023-10-03T17:23:56+00:00

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

4 files in total.
101 relevant lines, 101 lines covered and 0 lines missed. ( 100.0% )
File % covered Lines Relevant Lines Lines covered Lines missed Avg. Hits / Line
lib/repo_small_badge.rb 100.00 % 10 4 4 0 1.00
lib/repo_small_badge/configuration.rb 100.00 % 105 53 53 0 4.15
lib/repo_small_badge/image.rb 100.00 % 100 37 37 0 2.30
spec/support/mocks.rb 100.00 % 83 7 7 0 1.43

lib/repo_small_badge.rb

100.0% lines covered

4 relevant lines. 4 lines covered and 0 lines missed.
    
  1. # frozen_string_literal: true
  2. # :nodoc:
  3. 1 module RepoSmallBadge
  4. end
  5. 1 $LOAD_PATH.unshift(File.join(File.dirname(__FILE__)))
  6. 1 require 'repo_small_badge/version'
  7. 1 require 'repo_small_badge/image'

lib/repo_small_badge/configuration.rb

100.0% lines covered

53 relevant lines. 53 lines covered and 0 lines missed.
    
  1. # frozen_string_literal: true
  2. 1 module RepoSmallBadge
  3. # Hidden class to handle the interface to configuration
  4. 1 class Configuration
  5. 1 def initialize(config_hash)
  6. 4 @config = config_hash
  7. end
  8. 1 def merge!(new_config)
  9. 1 @config.merge!(new_config)
  10. end
  11. 1 def value_background
  12. 3 @config.fetch(:value_background, '#4c1')
  13. end
  14. 1 def value_color
  15. 3 @config.fetch(:value_color, title_color)
  16. end
  17. 1 def value_font
  18. 3 @config.fetch(:value_font, font)
  19. end
  20. 1 def value_font_size
  21. 3 @config.fetch(:value_font_size, font_size)
  22. end
  23. 1 def title_background
  24. 3 @config.fetch(:title_background, '#555')
  25. end
  26. 1 def background
  27. 3 @config.fetch(:background, '#fff')
  28. end
  29. 1 def title_font
  30. 3 @config.fetch(:title_font, font)
  31. end
  32. 1 def title_font_size
  33. 3 @config.fetch(:title_font_size, font_size)
  34. end
  35. 1 def title_color
  36. 6 @config.fetch(:title_color, '#fff')
  37. end
  38. 1 def font
  39. 6 @config.fetch(:font, 'Verdana,sans-serif')
  40. end
  41. 1 def font_size
  42. 6 @config.fetch(:font_size, 11).to_s
  43. end
  44. 1 def rounded_edge_radius
  45. 3 if @config.fetch(:rounded_border, true)
  46. 2 @config.fetch(:rounded_edge_radius, '3')
  47. else
  48. 1 0
  49. end
  50. end
  51. 1 def badge_width
  52. 46 @config.fetch(:badge_width, 120).to_i
  53. end
  54. 1 def badge_height
  55. 28 @config.fetch(:badge_height, 20).to_i
  56. end
  57. 1 def badge_middle
  58. 27 @config.fetch(:badge_middle, badge_width / 2).to_i
  59. end
  60. 1 def title_middle
  61. 6 badge_middle / 2
  62. end
  63. 1 def value_middle
  64. 6 badge_middle + (badge_width - badge_middle) / 2
  65. end
  66. 1 def filename(suffix = '')
  67. 3 prefix = @config.fetch(:filename_prefix, 'badge')
  68. 3 format = @config.fetch(:format, 'svg')
  69. 3 "#{output_path}/#{prefix}_#{suffix}.#{format}"
  70. end
  71. 1 def title(suffix)
  72. 6 prefix = @config.fetch(:title_prefix, '')
  73. 6 if prefix.to_s.empty?
  74. 4 suffix
  75. else
  76. 2 "#{@config.fetch(:title_prefix, '')} #{suffix}"
  77. end
  78. end
  79. 1 def output_path
  80. 3 @config.fetch(:output_path, '.')
  81. end
  82. end
  83. end

lib/repo_small_badge/image.rb

100.0% lines covered

37 relevant lines. 37 lines covered and 0 lines missed.
    
  1. # frozen_string_literal: true
  2. 1 require 'victor'
  3. 1 require 'repo_small_badge/configuration'
  4. 1 module RepoSmallBadge
  5. # Class that creates the Badge SVG image.
  6. # Behaviour is defined by the configuration hash.
  7. # For the different configurables see RepoSmallBadge::Configuration.
  8. 1 class Image < Victor::SVGBase
  9. # Create new instance.
  10. # @config is a Hash of configurables. Keys are symbols.
  11. 1 def initialize(config = {})
  12. 4 @config = Configuration.new(config)
  13. 4 super(template: :html, contentScriptType: 'text/ecmascript',
  14. contentStyleType: 'text/css', preserveAspectRatio: 'xMidYMid meet',
  15. version: '1.0',
  16. height: @config.badge_height, width: @config.badge_width)
  17. end
  18. # Creates the badge.
  19. # @name the suffix for the filename (badge_#{name})
  20. # @title the title of the badge.
  21. # @value is the overall value to be written to the right side of the badge.
  22. 1 def badge(name, title, value)
  23. 3 svg_header
  24. 3 svg_rounded_box
  25. 3 svg_boxes
  26. 3 svg_title(title)
  27. 3 svg_value(value)
  28. 3 save(@config.filename(name))
  29. end
  30. # Updates the configuration settings and overwrites existing ones.
  31. # @config the hash that has to be merged.
  32. 1 def config_merge(config)
  33. 1 @config.merge!(config)
  34. end
  35. 1 private
  36. 1 def svg_header
  37. 3 element :linearGradient, id: 'smooth', x2: '0', y2: @config.badge_width do
  38. 3 element :stop, offset: '0', 'stop-color': '#bbb', 'stop-opacity': '.1'
  39. 3 element :stop, offset: '1', 'stop-opacity': '.1'
  40. end
  41. end
  42. # rubocop:disable Metrics/MethodLength
  43. 1 def svg_boxes
  44. 3 element :g, 'clip-path' => 'url(#round)' do
  45. 3 element :rect, height: @config.badge_height,
  46. width: @config.badge_middle,
  47. fill: @config.title_background
  48. 3 element :rect, x: @config.badge_middle,
  49. height: @config.badge_height,
  50. width: @config.badge_middle,
  51. fill: @config.value_background
  52. 3 element :rect, height: @config.badge_height,
  53. width: @config.badge_width, fill: 'url(#smooth)'
  54. end
  55. # rubocop:enable Metrics/MethodLength
  56. end
  57. 1 def svg_rounded_box
  58. 3 element :clipPath, id: 'round' do
  59. 3 element :rect, height: @config.badge_height, width: @config.badge_width,
  60. rx: @config.rounded_edge_radius, fill: @config.background
  61. end
  62. end
  63. 1 def svg_title(title)
  64. 3 element :g, fill: @config.title_color, 'text-anchor': 'middle',
  65. 'font-family': @config.title_font,
  66. 'font-size': @config.title_font_size do |_svg|
  67. 3 element :text, @config.title(title),
  68. x: @config.title_middle, y: @config.badge_height - 5,
  69. fill: '#010101', 'fill-opacity': '0.3'
  70. 3 element :text, @config.title(title),
  71. x: @config.title_middle, y: @config.badge_height - 6
  72. end
  73. end
  74. # rubocop:disable Metrics/MethodLength
  75. 1 def svg_value(value)
  76. 3 element :g, fill: @config.value_color, 'text-anchor': 'middle',
  77. 'font-family': @config.value_font,
  78. 'font-size': @config.value_font_size do |_svg|
  79. 3 element :text, value,
  80. x: @config.value_middle,
  81. y: @config.badge_height - 5,
  82. fill: '#010101', 'fill-opacity': '0.3'
  83. 3 element :text, value,
  84. x: @config.value_middle,
  85. y: @config.badge_height - 6
  86. end
  87. end
  88. # rubocop:enable Metrics/MethodLength
  89. end
  90. end

spec/support/mocks.rb

100.0% lines covered

7 relevant lines. 7 lines covered and 0 lines missed.
    
  1. # frozen_string_literal: true
  2. 1 module TestRepoSmallBadge
  3. # rubocop:disable Metrics/MethodLength,Metrics/LineLength,Metrics/ParameterLists
  4. 1 def rounded_svg_string(title_color: '#fff', title_font: 'Verdana,sans-serif', title_font_size: 11,
  5. value_color: '#fff', value_font: 'Verdana,sans-serif', value_font_size: 11,
  6. width: 120, middle: 60)
  7. 2 %(<svg contentScriptType="text/ecmascript" contentStyleType="text/css" preserveAspectRatio="xMidYMid meet" version="1.0" height="20" width="#{width}"
  8. xmlns="http://www.w3.org/2000/svg"
  9. xmlns:xlink="http://www.w3.org/1999/xlink">
  10. <linearGradient id="smooth" x2="0" y2="#{width}">
  11. <stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
  12. <stop offset="1" stop-opacity=".1"/>
  13. </linearGradient>
  14. <clipPath id="round">
  15. <rect height="20" width="#{width}" rx="3" fill="#fff"/>
  16. </clipPath>
  17. <g clip-path="url(#round)">
  18. <rect height="20" width="#{middle}" fill="#555"/>
  19. <rect x="#{middle}" height="20" width="#{middle}" fill="#4c1"/>
  20. <rect height="20" width="#{width}" fill="url(#smooth)"/>
  21. </g>
  22. <g fill="#{title_color}" text-anchor="middle" font-family="#{title_font}" font-size="#{title_font_size}">
  23. <text x="#{middle / 2}" y="15" fill="#010101" fill-opacity="0.3">
  24. Total
  25. </text>
  26. <text x="#{middle / 2}" y="14">
  27. Total
  28. </text>
  29. </g>
  30. <g fill="#{value_color}" text-anchor="middle" font-family="#{value_font}" font-size="#{value_font_size}">
  31. 2 <text x="#{middle + (width - middle) / 2}" y="15" fill="#010101" fill-opacity="0.3">
  32. 100%
  33. </text>
  34. 2 <text x="#{middle + (width - middle) / 2}" y="14">
  35. 100%
  36. </text>
  37. </g>
  38. </svg>)
  39. end
  40. 1 def not_rounded_svg_string
  41. 1 %(<svg contentScriptType="text/ecmascript" contentStyleType="text/css" preserveAspectRatio="xMidYMid meet" version="1.0" height="20" width="200"
  42. xmlns="http://www.w3.org/2000/svg"
  43. xmlns:xlink="http://www.w3.org/1999/xlink">
  44. <linearGradient id="smooth" x2="0" y2="200">
  45. <stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
  46. <stop offset="1" stop-opacity=".1"/>
  47. </linearGradient>
  48. <clipPath id="round">
  49. <rect height="20" width="200" rx="0" fill="#fff"/>
  50. </clipPath>
  51. <g clip-path="url(#round)">
  52. <rect height="20" width="100" fill="#555"/>
  53. <rect x="100" height="20" width="100" fill="#4c1"/>
  54. <rect height="20" width="200" fill="url(#smooth)"/>
  55. </g>
  56. <g fill="#fff" text-anchor="middle" font-family="Verdana,sans-serif" font-size="11">
  57. <text x="50" y="15" fill="#010101" fill-opacity="0.3">
  58. badge Total
  59. </text>
  60. <text x="50" y="14">
  61. badge Total
  62. </text>
  63. </g>
  64. <g fill="#fff" text-anchor="middle" font-family="Verdana,sans-serif" font-size="11">
  65. <text x="150" y="15" fill="#010101" fill-opacity="0.3">
  66. 100%
  67. </text>
  68. <text x="150" y="14">
  69. 100%
  70. </text>
  71. </g>
  72. </svg>)
  73. end
  74. # rubocop:enable Metrics/MethodLength,Metrics/LineLength,Metrics/ParameterLists
  75. end