profile
viewpoint
Justin Searls searls @testdouble Orlando, FL, USA https://blog.testdouble.com/authors/justin-searls I talk to humans and also write code. I co-founded @testdouble, which is trying to make everything in software just a little bit less awful.

penelopezone/rubyfmt 787

Ruby Autoformatter!

krishkumar/BlockParty 746

Ad Blocker App for iOS, macOS

gel-rb/gel 611

A modern gem manager

felixge/node-sandboxed-module 339

A sandboxed node.js module loader that lets you inject dependencies into your modules.

rails/marcel 307

Find the mime type of files, examining file, filename and declared type

michaelfeathers/scythe 213

A tool for detecting barely used code in production

davemo/jasmine-only 17

Exclusivity spec helpers for jasmine that let you isolate spec runs to only one `describe` or `it`

gaslight/cskoans-online 5

Online version of the Coffeescript Koans

Schoonology/diplomat 3

Opinionated tool for end-to-end tests of HTTP APIs.

pull request commenttestdouble/standard

add ruby 3.0

Could you help by providing some context to what this PR is trying to do? IIRC, Style/HashExcept is already enabled in config/base.yml, which all projects targeting Rubies 2.5 & up will be loaded by standard

grosser

comment created time in 28 minutes

issue closedtestdouble/testdouble.js

No way to stub private module functions with test double

Description

No way to stub private module functions. At least I think so as I haven't found any way to do it in the docs.

Issue

I am unit testing a module. Lets say it's moduleA.js

function saySecret() {
  // Some complicated and possibly side effects
  // operations which are
  // not important for sayHi() test
  return 'Few possible options which are not important';
}

function sayHi(password) {
  let sayHiReturnedValue = 'some value';
  if (password) {
    sayHiReturnedValue += ` ${saySecret()}`; // 👈 Calling the non-export function
  }
  return sayHiReturnedValue;
}

module.exports = { sayHi };

Now the unit itself:

const { expect } = require('chai');
const td = require('testdouble');

const anything = td.matchers.anything();

describe('sayHi()', function () {
  beforeEach(() => {
    td.reset();
    delete require.cache[require.resolve('../../moduleA')];

    this.moduleA = require('../../moduleA');
  });

  it('Should return expected value', () => {
    // ❗ What I would like to achieve: ❗
    const saySecret = td.replace(`somehow replace saySecret()`); // 👈
    td.when(saySecret(anything)).thenReturn('controlled value'); // 👈

    const testedValue = this.moduleA.sayHi('something');
    expect(testedValue).to.equal('some value controlled value');
  });
});

I have found some other lib which makes it possible but installing that is not an option as I would need to get unlimited amount of permissions. The lib is called rewire and all the steps how to do it are described here. I just want to know if testdouble will give me that option. And if so how to achieve that.

Environment

  • [x] node -v output: v14.18.1
  • [x] npm -v (or yarn --version) output: 6.14.15
  • [x] npm ls testdouble (or yarn list testdouble) version: testdouble@3.16.1

closed time in 2 days

kapalkat

issue commenttestdouble/testdouble.js

No way to stub private module functions with test double

This is by design. The goal of testdouble.js is to facilitate test-driven development of a given unit by faking out that unit's dependencies via public interfaces.

In this presentation I talk a bit about why mocking private APIs is discouraged.

kapalkat

comment created time in 2 days

PullRequestReviewEvent

Pull request review commenttestdouble/bored

Issue #2 search for activity by ID (key)

 def test_that_it_gives_you_an_activity     assert (0..1).cover?(activity.price)     assert [String, NilClass].include?(activity.link.class)   end++  def test_that_it_gives_you_an_activity_with_a_specific_key+    activity = Bored.now(key: "1878070")++    assert_kind_of String, activity.description+    assert_equal "Volunteer at your local food pantry", activity.description+    assert_includes([+      :education, :recreational, :social, :diy, :charity,+      :cooking, :relaxation, :music, :busywork+    ], activity.type)+  end++  def test_that_it_gives_you_an_error_with_a_bad_key+    activity = Bored.now(key: "bogus")++    assert_kind_of String, activity.description+    assert_equal "No activity found with the specified parameters", activity.description+  end

I think that providing a known key and getting a 404 would be an exceptional-enough condition that we might want to consider raising an error in this case. What do you think?

lsparlin

comment created time in 5 days

PullRequestReviewEvent

Pull request review commenttestdouble/bored

Search by participant count

 def test_that_it_gives_you_an_activity     assert (0..1).cover?(activity.price)     assert [String, NilClass].include?(activity.link.class)   end++  def test_that_you_can_query_by_participants+    activity = Bored.now(participants: 3)++    assert_kind_of Numeric, activity.id+    assert_kind_of String, activity.description+    assert_includes([+      :education, :recreational, :social, :diy, :charity,+      :cooking, :relaxation, :music, :busywork+    ], activity.type)+    assert_equal 3, activity.participants+    assert (0..1).cover?(activity.accessibility)+    assert (0..1).cover?(activity.price)+    assert [String, NilClass].include?(activity.link.class)+  end

Given that we already have a test for the presence of the other fields, I think it'd probably be sufficient to only assert that the activity.participants is 3. Does that sound ok to you?

jonathanpike

comment created time in 5 days

PullRequestReviewEvent
PullRequestReviewEvent

push eventtestdouble/good-migrations

Justin Searls

commit sha 6f9e729ad3fbc6336d59ea37c2269fa1bc136288

that was a nice try, but zeitwerk requires ruby 2.5

view details

push time in 10 days

PR closed testdouble/good-migrations

Add a configuration for the error message

I would like to be able to configure the message for these reasons:

  • I have helpers available in my migrations to help for migrations that need to deal with translations. (We have a table for user-provided translations related to some models)
  • I would like to provide additional guidance and links for useful references.

I didn't really know how to test this because RaisesLoadError just uses GoodMigrations.config. I could refactor RaisesLoadError to have an initialize with a config parameter, but as a PR submitter, it's always awkward to change the structure of a project like that without first having the agreement of the maintainer. What do you think?

+56 -38

1 comment

3 changed files

MaxLap

pr closed time in 10 days

pull request commenttestdouble/good-migrations

Add a configuration for the error message

I'm sorry, but I'm not interested in making the message configurable. In general I want to keep this gem as simple as possible.

MaxLap

comment created time in 10 days

push eventtestdouble/good-migrations

Justin Searls

commit sha 872731782bf38eb170223473fa00ee4fd0a22be9

Specify 2.3 support and add it to the build matrix cc/ @maxlap #29

view details

push time in 10 days

PR closed testdouble/good-migrations

Tiny tweaks

Just two little tweaks I made as I worked on other things on the gem.

  • I think it's important to have a clear required_ruby_version in the gem_spec.
  • I think the clarification that there are many ways the models could already be loaded is important.
+5 -0

1 comment

2 changed files

MaxLap

pr closed time in 10 days

pull request commenttestdouble/good-migrations

Tiny tweaks

I'll add a minimum gem requirement, but I'm going to keep the comment as it is.

MaxLap

comment created time in 10 days

issue commenttestdouble/testdouble.js

td.replaceEsm() without namedExportStubs throws weird error under windows

Interesting! Other than tagging @giltayar for help, I wonder if this issue also exists under Windows under the latest Node 16.13.0?

jishi

comment created time in 10 days

created tagtestdouble/minitest-suite

tagv0.0.3

Re-order your Minitest suite into logical sub-suites/groups

created time in 13 days

push eventtestdouble/minitest-suite

Justin Searls

commit sha d4b5f9598c3b719457506e914eff06daa1d7659b

Add support for inheriting suite from parent

view details

Justin Searls

commit sha a79a619ea708bafa8d00bf28a8e86319aef4cfd7

0.0.3

view details

push time in 13 days

pull request commenttestdouble/cypress-capybara

Add a check for existence of "for"

Released in 0.0.3

On Nov 18, 2021, at 00:43, Ivan Kerin ***@***.***> wrote:

If there is no "for" selector found, then we must be in the case of a label wrapping the input + some text.

<label>

<input type="checkbox " /> Some label text

</label> in this case we usually want to click / interact with the label itself.

This is a rather quick fix, for something more elaborate we might want to find the actual input itself, but its better than the current implementation.

You can view, comment on, or merge this pull request online at:

https://github.com/testdouble/cypress-capybara/pull/1

Commit Summary

• 9716f66 Add a check for existence of "for" File Changes (1 file) • M lib/build-command.js (2) Patch Links:

• https://github.com/testdouble/cypress-capybara/pull/1.patch • https://github.com/testdouble/cypress-capybara/pull/1.diff — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or unsubscribe.

ivank

comment created time in 13 days

push eventtestdouble/cypress-capybara

Justin Searls

commit sha 118e464e9b69c9f8c8429743a514102787ab233c

0.0.3

view details

push time in 13 days

PR merged testdouble/cypress-capybara

Add a check for existence of "for"

If there is no "for" selector found, then we must be in the case of a label wrapping the input + some text.

<label>
  <input type="checkbox" />
  Some label text
</label>

in this case we usually want to click / interact with the label itself.

This is a rather quick fix, for something more elaborate we might want to find the actual input itself, but its better than the current implementation.

+1 -1

0 comment

1 changed file

ivank

pr closed time in 13 days

push eventtestdouble/cypress-capybara

Ivan Kerin

commit sha 9716f6617868985f5ed3e9073e21e4f3614bc49a

Add a check for existence of "for" If there is no "for" selector found, then we must be in the case of a label wrapping the input + some text. ```html <label> <input type="checkbox" /> Some label text </label> ``` in this case we usually want to click / interact with the label itself. This is a rather quick fix, for something more elaborate we might want to find the actual input itself, but its better than the current implementation.

view details

Justin Searls

commit sha 297d8b09a8bd7a4f5d1020f922cdc2229ed264fe

Merge pull request #1 from ivank/patch-1 Add a check for existence of "for"

view details

push time in 13 days

push eventtestdouble/cypress-capybara

Ivan Kerin

commit sha b124d6e49ea8144a53bc81794451d5e33865c5dc

Support "[role=button]" style as well Material UI has a tendency to use divs and spans, instead of proper semantic html for some reason. But they are careful to add role=button to things that should act as buttons. Since this is in the spirit of what the selector wants to target, maybe its worth adding it here?

view details

Justin Searls

commit sha 2d8b58a58311a8a298a269f6059d22f2e0be2c1a

Merge pull request #2 from ivank/patch-2 Support "[role=button]" style as well

view details

push time in 13 days

PR merged testdouble/cypress-capybara

Support "[role=button]" style as well

Material UI has a tendency to use divs and spans, instead of proper semantic html for some reason. But they are careful to add role=button to things that should act as buttons. Since this is in the spirit of what the selector wants to target, maybe its worth adding it here?

+2 -1

1 comment

1 changed file

ivank

pr closed time in 13 days

pull request commenttestdouble/cypress-capybara

Support "[role=button]" style as well

Seems fine?

ivank

comment created time in 13 days

pull request commenttestdouble/good-migrations

Add permit_autoload_before_date configuration

Thank you for your contribution, @MaxLap! I've merged and released this in 0.2.0

MaxLap

comment created time in 13 days

PR merged testdouble/good-migrations

Add permit_autoload_before_date configuration

As discussed in https://github.com/testdouble/good-migrations/issues/25, this adds a basic configuration system and the permit_autoload_date_before configuration.

I didn't do the callable configuration part, as I would prefer to first add some easy to code configurations and then see if it still feels useful. This way, I can also have some feedback on how I've been doing things up to now.

There are a few unrelated changes that are just general improvement to the gem. They can be removed if you prefer, but I think they are clear improvements. Each commit is a coherent change, so you can view commit by commit.

+210 -27

1 comment

16 changed files

MaxLap

pr closed time in 13 days

created tagtestdouble/good-migrations

tagv0.2.0

Prevent Rails from auto-loading app/ code when running database migrations

created time in 13 days

push eventtestdouble/good-migrations

Maxime Lapointe

commit sha 9224ec202702163765e143a5d8b0788e2e2bcaea

Make tests run faster Locally, went from 77s to 20s

view details

Maxime Lapointe

commit sha e13661fd0f81b971659d656bc0357211dbad8186

Remove unused test setup

view details

Maxime Lapointe

commit sha e038d76273e77856abf1fda9ac2530a6acef6496

Add permit_autoloading_before_date configuration

view details

Maxime Lapointe

commit sha e86556b295d91816ef9333a7cc542e0731e401e5

Rename PreventsAppLoad -> Logic We are going to add some functions which are a bit more generic, I think it makes sense for the module to also be generic.

view details

Maxime Lapointe

commit sha 5966ed57f3fbbb10eb32c223aa95bdb1b5725565

Adding Logic.permit_autoloading_of_path? This is the method which contains the full default logic to decide if we allow or not.

view details

Maxime Lapointe

commit sha 7e14c5356f4c1db5b2e2945ca74ce3973e0ae70a

Adding test for permit_autoload_before_date Made a distinct model so that the 2nd dangerous migration wouldn't have the 1st one's loaded model during the test

view details

Maxime Lapointe

commit sha 2e7fad814059495f4b0776ee0920a694f5a5c9d7

Adding tests for the various ways to set permit_autoloading_before_date

view details

Maxime Lapointe

commit sha 6359df680016355b2caf2dd3bd515e9b46327bde

Add permit_autoloading_before_date to the README And rework the README a little bit

view details

Maxime Lapointe

commit sha 755ed67bbeb18abe03225f910ecc7d35ec22e9c9

Add changelog entry for permit_autoloading_before_date configuration

view details

Maxime Lapointe

commit sha 72a1297475a48b02a8af5fda4356bde11fac1ab9

Check if GoodMigration is enabled before checking if autoload is permitted

view details

Maxime Lapointe

commit sha b72e62893a2b0cde4d0e178f3ec62471f40b99c2

Use require_relative It's a bit faster when loading the gem, and it's free!

view details

Maxime Lapointe

commit sha d2488db51d6ef13003ebc40c3b654e16fba6600d

Extract a MigrationDetails class from Logic

view details

Maxime Lapointe

commit sha 9434a6af04533ae1e46a9baf34d258f43fa0e3b1

Make configuration a singleton PORO

view details

Justin Searls

commit sha ec0a70046fcd116d0bc954a3be679d8eb09a30bb

Adjust permit_autoloading_before option before merge * Rename the option to `permit_autoloading_before` because `date` is a misnomer * Make the `config` option take a block, which is pretty conventional for initializers of gems * Update readme with more context (the option should really be last resort when more invasive approaches are inappropriate)

view details

Justin Searls

commit sha 75bd0b627001bca8062b5a056a1b7ae8d43e76b3

Refactor into POROs

view details

Justin Searls

commit sha ad925a391762e2dec134231bba622bb5c515a3f4

0.2.0

view details

push time in 13 days

Pull request review commenttestdouble/good-migrations

Add permit_autoload_before_date configuration

+module GoodMigrations+  class Configuration+    class << self+      # Migrations with timestamps (the numbers at the beginning of the file name) from+      # before this configured time will be allowed to perform autoloading, bypassing the+      # mechanism of this gem. Accepts:+      #   nil: meaning never permit it+      #   String accepted by `Time.parse`, such as: 20211103150610 or 20211103_150610+      #   object responding to `to_time`, such as Date and Time+      def permit_autoloading_before_date=(value)+        case value+        when nil+          # Stay nil+        when String+          value = Time.parse(value)+        else+          if value.respond_to?(:to_time)+            value = value.to_time+          else+            raise "Received an invalid value for permit_autoloading_before_date: #{value.inspect}"+          end+        end+        @permit_autoloading_before_date = value

This might look more natural to me:

        return unless value.present?
        
        @permit_autoloading_before_date = if value.is_a?(String)
          Time.parse(value)
        elsif value.respond_to?(:to_time)
          value.to_time
        else
          raise "Received an invalid value for permit_autoloading_before_date: #{value.inspect}"
        end
MaxLap

comment created time in 16 days

more