brut 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/bin/bin_kit.rb +12 -0
- data/bin/setup +11 -2
- data/lib/brut/cli/apps/scaffold.rb +1 -1
- data/lib/brut/front_end/component.rb +1 -1
- data/lib/brut/front_end/templates/locator.rb +1 -1
- data/lib/brut/i18n/base_methods.rb +13 -2
- data/lib/brut/junk_drawer.rb +1 -1
- data/lib/brut/spec_support/clock_support.rb +5 -0
- data/lib/brut/spec_support/component_support.rb +4 -0
- data/lib/brut/spec_support/enhanced_node.rb +2 -0
- data/lib/brut/spec_support/flash_support.rb +5 -0
- data/lib/brut/spec_support/general_support.rb +12 -0
- data/lib/brut/spec_support/handler_support.rb +2 -0
- data/lib/brut/spec_support/matcher.rb +1 -0
- data/lib/brut/spec_support/session_support.rb +2 -0
- data/lib/brut/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 52658877be0d3d968e4bcf7fea163aded14460e1d5027450f7e981bce2e972be
|
4
|
+
data.tar.gz: 4f415cd218aeec5eb4ad1f30eb686a2b41ac3293a71a6b61635f2913c6afd6a9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49bc406aced82e963475446bedd3669133a055440bfaed9da7e6a2c58288b02717a64b4f3ffa4886bb651233d9de42956d973ccb4853235271083f19f7c8a927
|
7
|
+
data.tar.gz: 8e299c68165fc48700d8d7cc85bb7d12ddaf9fa96c7227043d893d4a4a378314a97279767e34425ce729810712eae7dacaa55326452a5ba79c645fe5ab4640e6
|
data/Gemfile.lock
CHANGED
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 "
|
69
|
-
|
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::
|
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
|
-
# @
|
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
|
-
|
116
|
+
subkey = Array(page).join(".")
|
117
|
+
key = ["pages.#{self.page_name}.#{subkey}"]
|
109
118
|
elsif component
|
110
|
-
|
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}"]
|
data/lib/brut/junk_drawer.rb
CHANGED
@@ -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
|
-
#
|
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,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
|
data/lib/brut/version.rb
CHANGED
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.
|
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-
|
10
|
+
date: 2025-02-20 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: irb
|