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 +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
|