nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: zauberzeug/nicegui
Pull request #1914 (2023-10-28 14:36:07)

Support return values of refreshable function
This PR solves #1845 by supporting return values of refreshable functions.


Patch:
diff --git a/nicegui/functions/refreshable.py b/nicegui/functions/refreshable.py
index ece64ee4..c10beef5 100644
--- a/nicegui/functions/refreshable.py
+++ b/nicegui/functions/refreshable.py
@@ -24,26 +24,25 @@ class RefreshableTarget:
     locals: List[Any] = field(default_factory=list)
     next_index: int = 0
 
-    def run(self, func: Callable[..., Any]) -> Union[None, Awaitable]:
+    def run(self, func: Callable[..., Any]) -> Union[Any, Awaitable]:
         """Run the function and return the result."""
         RefreshableTarget.current_target = self
         self.next_index = 0
         # pylint: disable=no-else-return
         if is_coroutine_function(func):
-            async def wait_for_result() -> None:
+            async def wait_for_result() -> Any:
                 with self.container:
                     if self.instance is None:
-                        await func(*self.args, **self.kwargs)
+                        return await func(*self.args, **self.kwargs)
                     else:
-                        await func(self.instance, *self.args, **self.kwargs)
+                        return await func(self.instance, *self.args, **self.kwargs)
             return wait_for_result()
         else:
             with self.container:
                 if self.instance is None:
-                    func(*self.args, **self.kwargs)
+                    return func(*self.args, **self.kwargs)
                 else:
-                    func(self.instance, *self.args, **self.kwargs)
-            return None  # required by mypy
+                    return func(self.instance, *self.args, **self.kwargs)
 
 
 class RefreshableContainer(Element, component='refreshable.js'):
@@ -75,7 +74,7 @@ class refreshable:
             return refresh
         return attribute
 
-    def __call__(self, *args: Any, **kwargs: Any) -> Union[None, Awaitable]:
+    def __call__(self, *args: Any, **kwargs: Any) -> Union[Any, Awaitable]:
         self.prune()
         target = RefreshableTarget(container=RefreshableContainer(), refreshable=self, instance=self.instance,
                                    args=args, kwargs=kwargs)


Test patch:
diff --git a/tests/test_refreshable.py b/tests/test_refreshable.py
index 3ddc0ecf..0f87a2d2 100644
--- a/tests/test_refreshable.py
+++ b/tests/test_refreshable.py
@@ -205,3 +205,16 @@ def test_refreshable_with_state(screen: Screen):
     screen.wait(0.5)
     screen.should_contain('A: 1')
     screen.should_contain('B: 1')
+
+
+def test_refreshable_with_return_value(screen: Screen):
+    @ui.refreshable
+    def number_ui() -> int:
+        ui.label('42')
+        return 42
+
+    answer = number_ui()
+    assert answer == 42
+
+    screen.open('/')
+    screen.should_contain('42')
Repository: zauberzeug/nicegui
Pull request #1915 (2023-10-28 14:47:51)

Raise exception if `ui.element` is called with an invalid HTML tag
This PR solves #1908 by checking the tag name against a regex.


Patch:
diff --git a/nicegui/element.py b/nicegui/element.py
index e4fef3ad..d0c6d355 100644
--- a/nicegui/element.py
+++ b/nicegui/element.py
@@ -46,6 +46,11 @@ PROPS_PATTERN = re.compile(r'''
 (?:$|\s)            # Match end of string or whitespace
 ''', re.VERBOSE)
 
+# https://www.w3.org/TR/xml/#sec-common-syn
+TAG_START_CHAR = r':|[A-Z]|_|[a-z]|[\u00C0-\u00D6]|[\u00D8-\u00F6]|[\u00F8-\u02FF]|[\u0370-\u037D]|[\u037F-\u1FFF]|[\u200C-\u200D]|[\u2070-\u218F]|[\u2C00-\u2FEF]|[\u3001-\uD7FF]|[\uF900-\uFDCF]|[\uFDF0-\uFFFD]|[\U00010000-\U000EFFFF]'
+TAG_CHAR = TAG_START_CHAR + r'|-|\.|[0-9]|\u00B7|[\u0300-\u036F]|[\u203F-\u2040]'
+TAG_PATTERN = re.compile(fr'^({TAG_START_CHAR})({TAG_CHAR})*$')
+
 
 class Element(Visibility):
     component: Optional[Component] = None
@@ -70,6 +75,8 @@ class Element(Visibility):
         self.id = self.client.next_element_id
         self.client.next_element_id += 1
         self.tag = tag if tag else self.component.tag if self.component else 'div'
+        if not TAG_PATTERN.match(self.tag):
+            raise ValueError(f'Invalid HTML tag: {self.tag}')
         self._classes: List[str] = []
         self._classes.extend(self._default_classes)
         self._style: Dict[str, str] = {}


Test patch:
diff --git a/tests/test_element.py b/tests/test_element.py
index 772f1511..33528171 100644
--- a/tests/test_element.py
+++ b/tests/test_element.py
@@ -1,3 +1,4 @@
+import pytest
 from selenium.webdriver.common.by import By
 
 from nicegui import ui
@@ -262,3 +263,15 @@ def test_default_style():
     button_f = ui.button()
     assert button_f._style.get('border') == '2px'
     assert button_f._style.get('padding') == '30px'
+
+
+def test_invalid_tags(screen: Screen):
+    good_tags = ['div', 'div-1', 'DIV', 'däv', 'div_x', '🙂']
+    bad_tags = ['<div>', 'hi hi', 'hi/ho', 'foo$bar']
+    for tag in good_tags:
+        ui.element(tag)
+    for tag in bad_tags:
+        with pytest.raises(ValueError):
+            ui.element(tag)
+
+    screen.open('/')
Repository: zauberzeug/nicegui
Pull request #2396 (2024-01-18 09:04:03)

Allow handling Mermaid errors on the server
As discussed in #2390, this PR allows to subscribe to Mermaid errors.

```py
ui.mermaid('''
graph LR;
    A --> B;
    A -> C;
''').on('error', lambda e: ui.label(e.args['message']))
```

![Screenshot 2024-01-18 at 10 03 51](https://github.com/zauberzeug/nicegui/assets/5767091/241c9fe8-8f5c-465f-ae9d-f7e0be2be012)



Patch:
diff --git a/nicegui/elements/mermaid.js b/nicegui/elements/mermaid.js
index 37e9c9be..35adcc74 100644
--- a/nicegui/elements/mermaid.js
+++ b/nicegui/elements/mermaid.js
@@ -21,7 +21,12 @@ export default {
       if (is_running) return;
       is_running = true;
       while (queue.length) {
-        await mermaid.run({ nodes: [queue.shift()] });
+        try {
+          await mermaid.run({ nodes: [queue.shift()] });
+        } catch (error) {
+          console.error(error);
+          this.$emit("error", error);
+        }
       }
       is_running = false;
     },
diff --git a/website/documentation/content/mermaid_documentation.py b/website/documentation/content/mermaid_documentation.py
index 7aa7ebe8..1920c77f 100644
--- a/website/documentation/content/mermaid_documentation.py
+++ b/website/documentation/content/mermaid_documentation.py
@@ -12,4 +12,16 @@ def main_demo() -> None:
     ''')
 
 
+@doc.demo('Handle errors', '''
+    You can handle errors by listening to the `error` event.
+    The event `args` contain the properties `hash`, `message`, `str` and an `error` object with additional information.
+''')
+def error_demo() -> None:
+    ui.mermaid('''
+    graph LR;
+        A --> B;
+        A -> C;
+    ''').on('error', lambda e: print(e.args['message']))
+
+
 doc.reference(ui.mermaid)


Test patch:
diff --git a/tests/test_mermaid.py b/tests/test_mermaid.py
index ce4e9ae3..850d9359 100644
--- a/tests/test_mermaid.py
+++ b/tests/test_mermaid.py
@@ -63,3 +63,15 @@ def test_create_dynamically(screen: Screen):
     screen.open('/')
     screen.click('Create')
     screen.should_contain('Node')
+
+
+def test_error(screen: Screen):
+    ui.mermaid('''
+    graph LR;
+        A --> B;
+        A -> C;
+    ''').on('error', lambda e: ui.label(e.args['message']))
+
+    screen.open('/')
+    screen.should_contain('Syntax error in text')
+    screen.should_contain('Parse error on line 3')
Repository: zauberzeug/nicegui
Pull request #2453 (2024-01-29 04:03:49)

Add loaded event which fires when source of ui.interactive_image changes
This pull request adds the feature requested on [Reddit r/nicegui](https://www.reddit.com/r/nicegui/comments/19dxkz2/spinner_during_loading_image_in_interactive_image/).


Patch:
diff --git a/nicegui/elements/interactive_image.js b/nicegui/elements/interactive_image.js
index 47bd8fa5..232e0640 100644
--- a/nicegui/elements/interactive_image.js
+++ b/nicegui/elements/interactive_image.js
@@ -76,6 +76,7 @@ export default {
       this.loaded_image_width = e.target.naturalWidth;
       this.loaded_image_height = e.target.naturalHeight;
       this.viewBox = `0 0 ${this.loaded_image_width} ${this.loaded_image_height}`;
+      this.$emit("loaded", { width: this.loaded_image_width, height: this.loaded_image_height, source: e.target.src });
     },
     onMouseEvent(type, e) {
       const width = this.src ? this.loaded_image_width : this.size ? this.size[0] : 1;
diff --git a/website/documentation/content/interactive_image_documentation.py b/website/documentation/content/interactive_image_documentation.py
index 5ea73e98..827a0c6e 100644
--- a/website/documentation/content/interactive_image_documentation.py
+++ b/website/documentation/content/interactive_image_documentation.py
@@ -51,4 +51,15 @@ def blank_canvas():
     ).classes('w-64 bg-blue-50')
 
 
+@doc.demo('Loaded event', '''
+    You can listen to the "loaded" event to know when the image has been loaded.
+''')
+def loaded_event():
+    import time
+
+    ii = ui.interactive_image('https://picsum.photos/640/360')
+    ii.on('loaded', lambda e: ui.notify(f'loaded {e.args}'))
+    ui.button('Change Source', on_click=lambda: ii.set_source(f'https://picsum.photos/640/360?time={time.time()}'))
+
+
 doc.reference(ui.interactive_image)


Test patch:
diff --git a/tests/test_interactive_image.py b/tests/test_interactive_image.py
index 8a20b23d..1967fd71 100644
--- a/tests/test_interactive_image.py
+++ b/tests/test_interactive_image.py
@@ -1,3 +1,5 @@
+from typing import List
+
 import pytest
 from selenium.webdriver.common.action_chains import ActionChains
 
@@ -74,3 +76,19 @@ def test_mousemove_event(screen: Screen, cross: bool):
         .pause(0.5) \
         .perform()
     assert counter['value'] > 0
+
+
+def test_loaded_event(screen: Screen):
+    sources: List[str] = []
+    ii = ui.interactive_image('https://picsum.photos/id/29/640/360')
+    ii.on('loaded', lambda e: sources.append(e.args['source']))
+    ui.button('Change Source', on_click=lambda: ii.set_source('https://picsum.photos/id/30/640/360'))
+
+    screen.open('/')
+    screen.wait(0.5)
+    assert len(sources) == 1
+    screen.click('Change Source')
+    screen.wait(1.5)
+    assert len(sources) == 2
+    assert sources[1].endswith('id/30/640/360')
+    assert screen.find_by_tag('img').get_attribute('src') == sources[1]
Repository: zauberzeug/nicegui
Pull request #2753 (2024-03-23 00:11:28)

Update ui.number after changing its limits
This PR solves an issue noticed by @eddie3ruff on #2743: The stepper buttons of a `ui.number` element didn't enforce the min and max values after changing these limits. Consider the following example:

```py
number = ui.number('Number', max=0, value=0)

def raise_max():
    number.max += 1

ui.button('Raise max', on_click=raise_max)
```

After raising the max, the stepper wouldn't allow changing the value, even though it could be edited via the input field. By triggering an update at the end of the min and max property setters, this problem is solved.


Patch:
diff --git a/nicegui/elements/number.py b/nicegui/elements/number.py
index d16f86ed..6bded210 100644
--- a/nicegui/elements/number.py
+++ b/nicegui/elements/number.py
@@ -72,8 +72,11 @@ class Number(ValidationElement, DisableableElement):
 
     @min.setter
     def min(self, value: float) -> None:
+        if self._props['min'] == value:
+            return
         self._props['min'] = value
         self.sanitize()
+        self.update()
 
     @property
     def max(self) -> float:
@@ -82,8 +85,11 @@ class Number(ValidationElement, DisableableElement):
 
     @max.setter
     def max(self, value: float) -> None:
+        if self._props['max'] == value:
+            return
         self._props['max'] = value
         self.sanitize()
+        self.update()
 
     @property
     def precision(self) -> Optional[int]:
diff --git a/nicegui/static/nicegui.js b/nicegui/static/nicegui.js
index 7dc9e35c..df797ffb 100644
--- a/nicegui/static/nicegui.js
+++ b/nicegui/static/nicegui.js
@@ -36,7 +36,7 @@ function runMethod(target, method_name, args) {
   if (element === null || element === undefined) return;
   if (method_name in element) {
     return element[method_name](...args);
-  } else if (method_name in element.$refs.qRef) {
+  } else if (method_name in (element.$refs.qRef || [])) {
     return element.$refs.qRef[method_name](...args);
   } else {
     return eval(method_name)(element, ...args);


Test patch:
diff --git a/tests/test_number.py b/tests/test_number.py
index 018d7164..3ff9699e 100644
--- a/tests/test_number.py
+++ b/tests/test_number.py
@@ -107,3 +107,21 @@ def test_int_float_conversion_on_error2(screen: Screen):
     element.send_keys(Keys.BACKSPACE)
     screen.should_contain('Error')
     assert element.get_attribute('value') == '1.0'
+
+
+def test_changing_limits(screen: Screen):
+    number = ui.number('Number', max=0, value=0)
+    ui.button('Raise max', on_click=lambda: setattr(number, 'max', 1))
+    ui.button('Step up', on_click=lambda: number.run_method('(e) => e.getNativeElement().stepUp()'))
+
+    screen.open('/')
+    screen.should_contain_input('0')
+
+    screen.click('Step up')
+    screen.should_contain_input('0')
+
+    screen.click('Raise max')
+    screen.should_contain_input('0')
+
+    screen.click('Step up')
+    screen.should_contain_input('1')
Repository: uber-web/baseui
Pull request #637 (2018-12-10 20:47:55)

fix(popover): fix onOpen/onClose callbacks
Correctly wires up the `onOpen` `onClose` callbacks for StatefulPopover that exist in the docs but not in the implementation.

#### Patch: Bug Fix?

Yes

#### Major: Breaking Change?

No

#### Minor: New Feature?

No

#### Tests Added + Pass?

Yes



Patch:
diff --git a/src/popover/stateful-container.js b/src/popover/stateful-container.js
index 67c86de1d..150b20f7a 100644
--- a/src/popover/stateful-container.js
+++ b/src/popover/stateful-container.js
@@ -74,12 +74,18 @@ class StatefulContainer extends React.Component<
     this.internalSetState(STATE_CHANGE_TYPE.open, {
       isOpen: true,
     });
+    if (this.props.onOpen) {
+      this.props.onOpen();
+    }
   }
 
   close() {
     this.internalSetState(STATE_CHANGE_TYPE.close, {
       isOpen: false,
     });
+    if (this.props.onClose) {
+      this.props.onClose();
+    }
   }
 
   internalSetState(type: StateChangeTypeT, changes: StateT) {


Test patch:
diff --git a/src/popover/__tests__/stateful-container.test.js b/src/popover/__tests__/stateful-container.test.js
index 333740021..0631efb03 100644
--- a/src/popover/__tests__/stateful-container.test.js
+++ b/src/popover/__tests__/stateful-container.test.js
@@ -233,6 +233,29 @@ describe('StatefulPopoverContainer', () => {
     expect(component).toHaveState('isOpen', true);
   });
 
+  test('onOpen/onClose callbacks', () => {
+    const props = {
+      onOpen: jest.fn(),
+      onClose: jest.fn(),
+    };
+    const children = jest.fn();
+
+    const component = shallow(
+      <StatefulContainer {...props}>{children}</StatefulContainer>,
+    );
+
+    component.instance().onMouseEnter();
+    expect(props.onOpen).toHaveBeenCalledTimes(1);
+    expect(props.onClose).toHaveBeenCalledTimes(0);
+
+    props.onOpen.mockClear();
+    props.onClose.mockClear();
+
+    component.instance().onMouseLeave();
+    expect(props.onOpen).toHaveBeenCalledTimes(0);
+    expect(props.onClose).toHaveBeenCalledTimes(1);
+  });
+
   test('null stateReducer', () => {
     const props = {
       content: jest.fn(),
Repository: uber-web/baseui
Pull request #666 (2018-12-18 19:25:19)

fix(header-navigation): use normal cursor
#### Patch: Bug Fix?

Yes

#### Description

For some reason the root header navigation element has `cursor: pointer`. This is unnecessary and misleading, and the interactive elements _within_ a header should be the ones controlling cursor behavior.



Patch:
diff --git a/src/header-navigation/styled-components.js b/src/header-navigation/styled-components.js
index 41d0fc1b0..3fc3ebcab 100644
--- a/src/header-navigation/styled-components.js
+++ b/src/header-navigation/styled-components.js
@@ -18,7 +18,6 @@ export const Root = styled('nav', props => {
   } = $theme;
   return {
     ...font400,
-    cursor: 'pointer',
     display: 'flex',
     paddingBottom: scale500,
     paddingTop: scale500,


Test patch:
diff --git a/src/header-navigation/__tests__/__snapshots__/styled-components.test.js.snap b/src/header-navigation/__tests__/__snapshots__/styled-components.test.js.snap
index 2637d0e93..f591ad027 100644
--- a/src/header-navigation/__tests__/__snapshots__/styled-components.test.js.snap
+++ b/src/header-navigation/__tests__/__snapshots__/styled-components.test.js.snap
@@ -28,7 +28,6 @@ Array [
 exports[`Header Navigation styled components StyledRoot Root: StyledRoot has correct styles 1`] = `
 Object {
   "borderBottom": "1px solid $theme.colors.border",
-  "cursor": "pointer",
   "display": "flex",
   "fontFamily": "$theme.typography.font400.fontFamily",
   "fontSize": "$theme.typography.font400.fontSize",
Repository: uber-web/baseui
Pull request #705 (2019-01-03 23:55:32)

fix(menu): fix overflow in menu


Patch:
diff --git a/src/menu/examples.js b/src/menu/examples.js
index 944cd8ea1..f4c5371c8 100644
--- a/src/menu/examples.js
+++ b/src/menu/examples.js
@@ -144,7 +144,6 @@ export default {
             style: {
               height: '150px',
               width: '350px',
-              overflow: 'auto',
             },
           },
           Option: {
diff --git a/src/menu/styled-components.js b/src/menu/styled-components.js
index c22b97c72..7ab51f83f 100644
--- a/src/menu/styled-components.js
+++ b/src/menu/styled-components.js
@@ -29,6 +29,7 @@ export const List = styled('ul', ({$theme}: StyledPropsT) => ({
   backgroundColor: $theme.colors.backgroundAlt,
   borderRadius: $theme.borders.radius300,
   boxShadow: $theme.lighting.shadow600,
+  overflow: 'auto',
 }));
 List.displayName = 'StyledList';
 


Test patch:
diff --git a/src/menu/__tests__/__snapshots__/styled-components.test.js.snap b/src/menu/__tests__/__snapshots__/styled-components.test.js.snap
index 0bfcad1e9..1b29bf54a 100644
--- a/src/menu/__tests__/__snapshots__/styled-components.test.js.snap
+++ b/src/menu/__tests__/__snapshots__/styled-components.test.js.snap
@@ -9,6 +9,7 @@ Object {
   "marginLeft": "0",
   "marginRight": "0",
   "marginTop": "0",
+  "overflow": "auto",
   "paddingBottom": "$theme.sizing.scale300",
   "paddingLeft": "0",
   "paddingRight": "0",
Repository: uber-web/baseui
Pull request #784 (2019-01-23 21:35:14)

fix(pagination): dropdown z-index bug
`Fixes #1, Fixes #2` <!-- remove the (`) quotes to link the issues -->

#### Description

before:
<img width="792" alt="screen shot 2019-01-22 at 11 16 24 am" src="https://user-images.githubusercontent.com/5317799/51638608-a4b9f200-1f13-11e9-99e7-dcca755825c0.png">

after:
<img width="552" alt="screen shot 2019-01-23 at 1 32 00 pm" src="https://user-images.githubusercontent.com/5317799/51638618-abe10000-1f13-11e9-9485-2ec2268f4af7.png">


#### Scope

- [x] Patch: Bug Fix


Patch:
diff --git a/src/pagination/styled-components.js b/src/pagination/styled-components.js
index 252f598cc..74a381291 100644
--- a/src/pagination/styled-components.js
+++ b/src/pagination/styled-components.js
@@ -34,6 +34,7 @@ export const DropdownMenu = styled(StyledList, ({$theme}) => ({
   marginTop: $theme.sizing.scale300,
   left: 0,
   right: 0,
+  zIndex: 1,
 }));
 
 export const DropdownButton = styled(StyledBaseButton, ({$theme}) => ({


Test patch:
diff --git a/src/pagination/__tests__/__snapshots__/styled-components.test.js.snap b/src/pagination/__tests__/__snapshots__/styled-components.test.js.snap
index e8abcf137..e240fbbcc 100644
--- a/src/pagination/__tests__/__snapshots__/styled-components.test.js.snap
+++ b/src/pagination/__tests__/__snapshots__/styled-components.test.js.snap
@@ -24,6 +24,7 @@ Object {
   "position": "absolute",
   "right": 0,
   "top": "auto",
+  "zIndex": 1,
 }
 `;
Repository: rwjblue/ember-cli-template-lint
Pull request #43 (2016-03-08 15:20:43)

Remove hardcoding of 2 char length for inverse block programs.


Patch:
diff --git a/ext/plugins/lint-block-indentation.js b/ext/plugins/lint-block-indentation.js
index 6602fd9..2b83803 100644
--- a/ext/plugins/lint-block-indentation.js
+++ b/ext/plugins/lint-block-indentation.js
@@ -87,7 +87,7 @@ module.exports = function(addonContext) {
   BlockIndentation.prototype.processNestedElseBlock = function(node) {
     var elseBlockStatement = node.inverse.body[0];
 
-    elseBlockStatement._startOffset = 7;
+    elseBlockStatement._startOffset = 5 + elseBlockStatement.path.original.length;
   };
 
   return BlockIndentation;


Test patch:
diff --git a/node-tests/unit/plugins/lint-block-indentation-test.js b/node-tests/unit/plugins/lint-block-indentation-test.js
index e1a8ccb..5b6ce2c 100644
--- a/node-tests/unit/plugins/lint-block-indentation-test.js
+++ b/node-tests/unit/plugins/lint-block-indentation-test.js
@@ -10,12 +10,19 @@ generateRuleTests({
     '<div><p>Stuff</p></div>',
     '<div>\n  <p>Stuff Here</p>\n</div>',
     '{{#if isMorning}}' +
-    '  Good morning\n' +
-    '{{else if isAfternoon}}' +
-    '  Good afternoon\n' +
-    '{{else}}\n' +
-    '  Good night\n' +
-    '{{/if}}'
+      '  Good morning\n' +
+      '{{else if isAfternoon}}' +
+      '  Good afternoon\n' +
+      '{{else}}\n' +
+      '  Good night\n' +
+      '{{/if}}',
+    '{{#if isMorning}}\n' +
+      '  Good morning\n' +
+      '{{else foo-bar isAfternoon}}\n' +
+      '  Good afternoon\n' +
+      '{{else}}\n' +
+      '  Good night\n' +
+      '{{/if}}'
   ],
 
   bad: [
Repository: rwjblue/ember-cli-template-lint
Pull request #188 (2017-01-12 14:02:29)

Update to use common extension for template linting.
Prior to this change the test files emitted from ember-cli-template-lint would not be disabled by the "no lint" checkbox in ember-cli's default test harness.

---

Without "Disable Linting" checked:

![screenshot](https://monosnap.com/file/2iJWWxKco9dX66CXrT9RztwKKR4eEx.png)

With "Disable Linting" checked:

![screenshot](https://monosnap.com/file/DgjttPHf02OLOrgiFZU8GL0fwnteqb.png)

rwjblue: /cc @vvohra

Patch:
diff --git a/broccoli-template-linter.js b/broccoli-template-linter.js
index 553e906..84a49bf 100644
--- a/broccoli-template-linter.js
+++ b/broccoli-template-linter.js
@@ -42,7 +42,7 @@ TemplateLinter.prototype = Object.create(Filter.prototype);
 TemplateLinter.prototype.constructor = TemplateLinter;
 
 TemplateLinter.prototype.extensions = ['hbs'];
-TemplateLinter.prototype.targetExtension = 'template-lint-test.js';
+TemplateLinter.prototype.targetExtension = 'template.lint-test.js';
 
 TemplateLinter.prototype.baseDir = function() {
   return __dirname;


Test patch:
diff --git a/node-tests/acceptance/broccoli-test.js b/node-tests/acceptance/broccoli-test.js
index 230a4b0..e7a5e93 100644
--- a/node-tests/acceptance/broccoli-test.js
+++ b/node-tests/acceptance/broccoli-test.js
@@ -55,7 +55,7 @@ describe('broccoli-template-linter', function() {
       .then(function(results) {
         var outputPath = results.directory;
         var contents = fs.readFileSync(
-          path.join(outputPath, 'templates', 'application.template-lint-test.js'),
+          path.join(outputPath, 'templates', 'application.template.lint-test.js'),
           { encoding: 'utf8' }
         );
 
@@ -75,7 +75,7 @@ describe('broccoli-template-linter', function() {
       .then(function(results) {
         var outputPath = results.directory;
         var contents = fs.readFileSync(
-          path.join(outputPath, 'templates', 'application.template-lint-test.js'),
+          path.join(outputPath, 'templates', 'application.template.lint-test.js'),
           { encoding: 'utf8' }
         );