brut 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d0a674e5f292d833626132e6cb0d634eb7432a5f814cfdde37456980c5066ace
4
- data.tar.gz: dfe06bd16d1af502fc42512c1eb9c6500d2f13e3355587e705bb3e0f314f59be
3
+ metadata.gz: 52658877be0d3d968e4bcf7fea163aded14460e1d5027450f7e981bce2e972be
4
+ data.tar.gz: 4f415cd218aeec5eb4ad1f30eb686a2b41ac3293a71a6b61635f2913c6afd6a9
5
5
  SHA512:
6
- metadata.gz: d6c1dae45c7e5f30b6e01ff4add890fbc3bbe1581c2363fa872a627d040f1dbe08a99e2d07c1f56e15d4f542cb506fa5a3e1f4d4ce4f0e15accba0ae3976b2fb
7
- data.tar.gz: bcdf28454960102dfc70dc7a2b74f52ab7b661a83cd6050473a3de28628c636fd02cb476b44c3ab7000d64500b494682780cd1f60b4d5da5f0747652d33917f9
6
+ metadata.gz: 49bc406aced82e963475446bedd3669133a055440bfaed9da7e6a2c58288b02717a64b4f3ffa4886bb651233d9de42956d973ccb4853235271083f19f7c8a927
7
+ data.tar.gz: 8e299c68165fc48700d8d7cc85bb7d12ddaf9fa96c7227043d893d4a4a378314a97279767e34425ce729810712eae7dacaa55326452a5ba79c645fe5ab4640e6
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- brut (0.0.3)
4
+ brut (0.0.4)
5
5
  concurrent-ruby
6
6
  i18n
7
7
  irb
data/bin/bin_kit.rb CHANGED
@@ -2,6 +2,18 @@ require "pathname"
2
2
  require "fileutils"
3
3
  require "open3"
4
4
 
5
+ def capture!(*args)
6
+ log "Executing #{args} and capturing results"
7
+ out,err,status = Open3.capture3(*args)
8
+ if status.success?
9
+ return [out,err]
10
+ else
11
+ $STDERR.puts out
12
+ $STDERR.puts err
13
+ log "#{args} failed"
14
+ abort
15
+ end
16
+ end
5
17
  # We don't want the setup method to have to do all this error
6
18
  # checking, and we also want to explicitly log what we are
7
19
  # executing. Thus, we use this method instead of Kernel#system
data/bin/setup CHANGED
@@ -65,8 +65,17 @@ def setup(update_gems:,setup_credentials:)
65
65
  x = gets
66
66
  end
67
67
 
68
- log "Adding your SSH key to ssh-agent - you must provide your passphrase"
69
- system! "ssh-add #{key_file}"
68
+ log "Checking if ssh-agent has your SSH key"
69
+ out,_err = capture!("ssh-keygen -lf #{key_file}")
70
+ sha256 = out.split(/SHA256:/)[1].split(/\s+/)[0]
71
+ command = "ssh-add -l | grep #{sha256} > /dev/null"
72
+ log "Running '#{command}' to check"
73
+ if system(command)
74
+ log "SSH Key is in ssh agent"
75
+ else
76
+ log "Adding your SSH key to ssh-agent - you must provide your passphrase"
77
+ system! "ssh-add #{key_file}"
78
+ end
70
79
 
71
80
  known_hosts_dest = Pathname("/") / "root" / ".ssh" / "known_hosts"
72
81
  if known_hosts_dest.exist?
@@ -470,7 +470,7 @@ end}
470
470
  handle_method_code = if form
471
471
  'raise "You need to implement your Handler\#{form.class.input_definitions.length < 2 ? " and likely your Form as well" : ""}"'
472
472
  else
473
- raise "You need to implement your Handler"
473
+ 'raise "You need to implement your Handler"'
474
474
  end
475
475
  handler_code = begin
476
476
  handle_params = []
@@ -215,7 +215,7 @@ class Brut::FrontEnd::Component
215
215
  end
216
216
 
217
217
  # Create an HTML input tag for the given input of a form. This is a convieniece method
218
- # that calls {Brut::FrontEnd::Components::Input::TextField.for_form_input}.
218
+ # that calls {Brut::FrontEnd::Components::Inputs::TextField.for_form_input}.
219
219
  def input_tag(form:, input_name:, index: nil, **html_attributes)
220
220
  component(Brut::FrontEnd::Components::Inputs::TextField.for_form_input(form:,input_name:,index:,html_attributes:))
221
221
  end
@@ -41,7 +41,7 @@ class Brut::FrontEnd::Templates::Locator
41
41
  # @param [String] base_name the base name of a file that is expected to have a template. This is searched relative to the paths
42
42
  # provided to the constructor, so it may have nested paths
43
43
  # @return [String] path to the template for the given `base_name`
44
- # @raises StandardError if zero or more than one templates are found
44
+ # @raise StandardError if zero or more than one templates are found
45
45
  def locate(base_name)
46
46
  paths_to_try = @paths.map { |path|
47
47
  path / "#{base_name}.#{@extension}"
@@ -31,6 +31,8 @@ module Brut::I18n::BaseMethods
31
31
  # is a `Brut::FrontEnd::Page` or is a page component. It's `page_name` will be used to create
32
32
  # a key based on the value of `page:`: `pages.«page_name».«page: value»`.
33
33
  # if `component:` is included, the behavior is the same but for `component` instead of `page`.
34
+ # Note that if the page– or component–specific key is not found, this will check
35
+ # `general.«page: value»`.
34
36
  # @option interpolated_values [Numeric] count Special interpolation to control pluralization.
35
37
  #
36
38
  # @raise [I18n::MissingTranslation] if no translation is found
@@ -66,6 +68,9 @@ module Brut::I18n::BaseMethods
66
68
  # @example Using page:
67
69
  # # in your translations file
68
70
  # en: {
71
+ # general: {
72
+ # new_widget: "Make a New Widget",
73
+ # },
69
74
  # pages: {
70
75
  # HomePage: {
71
76
  # new_widget: "Create new Widget"
@@ -79,6 +84,8 @@ module Brut::I18n::BaseMethods
79
84
  # t(page: :new_widget) # => Create new Widget
80
85
  # # in your code for WidgetsPage
81
86
  # t(page: :new_widget) # => Create New
87
+ # # in your code for SomeOtherEPage
88
+ # t(page: :new_widget) # => Make a New Widget
82
89
  #
83
90
  # @example Using page: with an array
84
91
  # # in your translations file
@@ -104,13 +111,17 @@ module Brut::I18n::BaseMethods
104
111
  raise ArgumentError, "You may only specify page or component, not both"
105
112
  end
106
113
 
114
+ subkey = nil
107
115
  if page
108
- key = ["pages.#{self.page_name}.#{Array(page).join('.')}"]
116
+ subkey = Array(page).join(".")
117
+ key = ["pages.#{self.page_name}.#{subkey}"]
109
118
  elsif component
110
- key = ["components.#{self.component_name}.#{Array(component).join('.')}"]
119
+ subkey = Array(component).join(".")
120
+ key = ["components.#{self.component_name}.#{subkey}"]
111
121
  else
112
122
  raise ArgumentError, "If you omit an explicit key, you must specify page or component"
113
123
  end
124
+ key << "general.#{subkey}"
114
125
  else
115
126
  key = Array(key).join('.')
116
127
  key = [key,"general.#{key}"]
@@ -8,7 +8,7 @@ class Clock
8
8
  #
9
9
  # @param [TZInfo::Timezone] tzinfo_timezone if present, this is the timezone of the clock.
10
10
  # @param [Time] now if omitted, uses `Time.now` when asked the current time. Otherwises, uses this value, as a `Time` for
11
- # now. Don't do this unless you are testing.
11
+ # now. Don't do this unless you are testing.
12
12
  def initialize(tzinfo_timezone, now: nil)
13
13
  if tzinfo_timezone
14
14
  @timezone = tzinfo_timezone
@@ -1,5 +1,10 @@
1
+ # Convienience methods for creating clocks needed in tests
1
2
  module Brut::SpecSupport::ClockSupport
3
+ # Return a real lock in UTC
2
4
  def real_clock = Clock.new(TZInfo::Timezone.get("UTC"))
5
+ # Return a clock whose value for now is `now`
6
+ #
7
+ # @param [String] now a string containing the value you want for {Clock#now} to return.
3
8
  def clock_at(now:)
4
9
  Clock.new(TZInfo::Timezone.get("UTC"), now: Time.parse(now))
5
10
  end
@@ -2,6 +2,8 @@ require_relative "flash_support"
2
2
  require_relative "session_support"
3
3
  require_relative "clock_support"
4
4
  require_relative "enhanced_node"
5
+
6
+ # Convienience methods for writing tests of components or pages.
5
7
  module Brut::SpecSupport::ComponentSupport
6
8
  include Brut::SpecSupport::FlashSupport
7
9
  include Brut::SpecSupport::SessionSupport
@@ -66,10 +68,12 @@ module Brut::SpecSupport::ComponentSupport
66
68
  Brut::SpecSupport::EnhancedNode.new(nokogiri_node)
67
69
  end
68
70
 
71
+ # @!visibility private
69
72
  def routing_for(klass,**args)
70
73
  Brut.container.routing.uri(klass,**args)
71
74
  end
72
75
 
76
+ # Escape HTML using the same code Brut uses for rendering templates.
73
77
  def escape_html(...)
74
78
  Brut::FrontEnd::Templates::EscapableFilter.escape_html(...)
75
79
  end
@@ -1,5 +1,7 @@
1
1
  require "delegate"
2
2
 
3
+ # A delegator to a Nokogiri Node that provides convienience methods
4
+ # for navigating the DOM inside a test.
3
5
  class Brut::SpecSupport::EnhancedNode < SimpleDelegator
4
6
  include RSpec::Matchers
5
7
 
@@ -1,6 +1,11 @@
1
+ # Convienience methods for using a Flash inside tests.
1
2
  module Brut::SpecSupport::FlashSupport
3
+ # Create a normal empty flash, using the app's configured class.
2
4
  def empty_flash = Brut.container.flash_class.new
3
5
 
6
+ # Create a flash using the app's configured class that contains the given hash as its values.
7
+ #
8
+ # @param [Hash] hash Values to include in the Flash.
4
9
  def flash_from(hash)
5
10
  Brut.container.flash_class.from_h(messages: hash)
6
11
  end
@@ -1,9 +1,16 @@
1
+ # Convienience methods included in all tests.
1
2
  module Brut::SpecSupport::GeneralSupport
2
3
  def self.included(mod)
3
4
  mod.extend(ClassMethods)
4
5
  end
5
6
 
6
7
  module ClassMethods
8
+ # To pass bin/test audit with a class whose implementation is trivial, call this inside the RSpec `describe` block. This is better
9
+ # than an empty test as it makes it more explicit that you believe the implementation is trivial enough to not require a test. You
10
+ # can also set an expiration for this thinking.
11
+ #
12
+ # @param [Time|String] check_again_at if given, this will cause the test to fail after the given date/time. If passed as a
13
+ # string, `Date.parse` is used to convert it to a `Time`.
7
14
  def implementation_is_trivial(check_again_at: nil)
8
15
  check_again_at = if check_again_at.nil?
9
16
  nil
@@ -20,6 +27,11 @@ module Brut::SpecSupport::GeneralSupport
20
27
  end
21
28
  end
22
29
  end
30
+
31
+ # Used when a class' implmentation is covered by other tests. This is better than omitting the test or having a blank one, as it
32
+ # makes it explicit that some other test covers this class' behavior.
33
+ #
34
+ # @param [String] description An explanation of what other tests cover this class' implementation.
23
35
  def implementation_is_covered_by_other_tests(description)
24
36
  it "has no tests because the implementation is sufficiently covered by other tests: #{description}" do
25
37
  expect(true).to eq(true)
@@ -1,6 +1,8 @@
1
1
  require_relative "flash_support"
2
2
  require_relative "clock_support"
3
3
  require_relative "session_support"
4
+
5
+ # Convienience methods for testing handlers.
4
6
  module Brut::SpecSupport::HandlerSupport
5
7
  include Brut::SpecSupport::FlashSupport
6
8
  include Brut::SpecSupport::ClockSupport
@@ -1,3 +1,4 @@
1
+ # Holds custom matchers useful in various tests.
1
2
  module Brut::SpecSupport::Matchers
2
3
  end
3
4
  require_relative "matchers/be_a_bug"
@@ -1,3 +1,5 @@
1
+ # Convienience methods for creating sessions inside a test.
1
2
  module Brut::SpecSupport::SessionSupport
3
+ # Create an empty session, using the class configured by the app
2
4
  def empty_session = Brut.container.session_class.new(rack_session: {})
3
5
  end
data/lib/brut/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Brut
2
2
  # @!visibility private
3
- VERSION = "0.0.3"
3
+ VERSION = "0.0.4"
4
4
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brut
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Bryant Copeland
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-02-19 00:00:00.000000000 Z
10
+ date: 2025-02-20 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: irb