Skip to content

Releases: getsaf/shallow-render

v9.0.1

09 Mar 00:37
Compare
Choose a tag to compare

Check out the new docs!

https://getsaf.github.io/shallow-render


Addresses deficiencies noted in #153

This allows mocking injection tokens directly like:

const STRING_TOKEN = new InjectionToken<string>('A string injection token');
const FUNCTION_TOKEN = new InjectionToken<() => string>('A function injection token');

// Can now be mocked with:
shallow
  .mock(STRING_TOKEN, 'mocked value')
  .mock(FUNCTION_TOKEN, () => 'mocked function return');

v8.5.2

09 Mar 00:41
Compare
Choose a tag to compare
  • Fix some test typing issues for Jest
  • Allow provideMock to work with useValue to allow for easy use of mock service classes:
provideMock({provide: Service, useValue: new MockService()});

v8.5.0

20 Sep 14:54
Compare
Choose a tag to compare

Fixes

#135
Another shot at fixing matchers for Jest (thanks for testing @ike18t and thanks for issues/code from @ericrav and @marcus-sa)

New features

#136

The ability to search for components/directives by Class and css styles

const greenFoo = findComponent(FooComponent, {query: '.green'})

The ability to search for structural directives

const {findStructuralDirective} = await shallow.render();
const fooDirective = findStructuralDirective(FooDirective);

-- or -- with a predicate

const {findStructuralDirective} = await shallow.render();
const fooDirective = findStructuralDirective(FooDirective, fd => fd.directiveProperty === 'cool');

Targeted rendering of structural directives

const {renderStructuralDirective} = await shallow.render();
renderStructuralDirective(FooDirective);
// Un-render with a second argument
renderStructuralDirective(FooDirective, false);

-- or -- render specific instances of a directive

const {findStructuralDirective, renderStructuralDirective} = await shallow.render();
const coolFooDirective = findStructuralDirective(FooDirective, fd => fd.directiveProperty === 'cool');
renderStructuralDirective(coolFooDirective);

Render-time control of structural directives

const shallow = new Shallow(TestComponent, TestModule)
  .withStructuralDirective(MyDirective)
  .withStructuralDirective(MyOtherDirective, false);

Global control of structural directives

Shallow
  .alwaysWithStructuralDirective(MyDirective)
  .alwaysWithStructuralDirective(MyOtherDirective, false);

v8.3.0

02 Aug 13:10
Compare
Choose a tag to compare
  • PR #127 fixes issues with EntryComponent testing. See issue #125 (thanks for digging into this @antch)
  • New provideMock feature allows adding providers with an empty mock in a single line (thanks @kylecannon ):
shallow = new Shallow(MyComponent, MyModule)
  .provideMock(FooService, BarService);

v8.2.2

19 Jul 23:50
Compare
Choose a tag to compare

Fixed the custom Jest matchers and updated the wiki to reflect that Jest Matchers are a thing!
Thanks for reporting the issue @ike18t

v8.2.1

19 Jul 23:49
Compare
Choose a tag to compare

Cosmetic fix for #119

v8.2.0

30 Jun 15:28
Compare
Choose a tag to compare
  • #117 - Support for rendering EntryComponents from an NgComponentOutlet.

Here's the rundown....

Entry Components

When rendering "normal" components, Angular looks for "selectors" in the template and searches in the module-tree for a component that matches the selector. In testing, we have total control over the module so we can swap out dummy components to match up with selectors and our tests are happy.

EntryComponents bypass this and are referenced directly by their class object instead of being plucked out of the module by their selectors. This can make components that render EntryComponents hard to test.

Here's what I mean:

@Injectable()
class ComponentService {
   getDynamicComponent() {
     return Math.random() === 1
       ? FooComponent
       : BarComponent;
   }
}
@Component({
  selector: 'foo',
  template: '<ng-container *ngComponentOutlet="componentService.getDynamicComponent()" />'
})
class MyComponent {
  constructor(public componentService: ComponentService) {}
}

If we want to test MyComponent, we have two options:

  1. Use the real ComponentService and render the real FooComponent or BarComponent. This is typically undesirable because Foo or Bar components could be complex which would require the tests for MyComponent to provide setup/mocks/etc to satisfy Foo and Bar components requirements.
  2. Mock the ComponentService and provide dummy entry components. 😎

Here's an example of option 2:

describe('option 2', () => {
  let shallow: Shallow<MyComponent>;
  @Component({selector: 'dummy', template: '<i></i>'})
  class DummyComponent {}

  beforeEach(() => {
    shallow = new Shallow(MyComponent, MyModule)
      .declare(DummyComponent)
      // We cannot mock the DummyComponent because the getDynamicComponent method below
      // will return the *REAL* component so the *actual* DummyComponent must exist in our test setup!
      .dontMock(DummyComponent)
      .mock(ComponentService, {getDynamicComponent: () => DummyComponent});
  });

  it('renders the component from the ComponentSevice', async () => {
    const {find} = await shallow.render();

    expect(find(DummyComponent)).toHaveFoundOne();
  });
});

This means that if we want to test an EntryComponent that is provided by an external service, we will be required to mock the service that provides the component and we will have to declare a suitable dummy component to render.

v8.1.0

31 May 12:55
Compare
Choose a tag to compare
  • Officially support Angular 8!
  • Fixed an issue where the customMatchers were not being imported properly into the jasmine/jest namespace

v8.0.5

31 May 12:54
Compare
Choose a tag to compare
  • Fix an edge-case when mocking modules and using AlwaysReplaceModule #108

v8.0.4

31 May 12:53
Compare
Choose a tag to compare
  • Upgrade ng-mocks to avoid a conflict