Skip to content

Commit

Permalink
Support JSX Factory
Browse files Browse the repository at this point in the history
Fixes cyclejs#8

Implementation of `jsxFactory` is just a copy and paste from @sliptype's
pull request (cyclejs/react-dom#3).
Test cases have been rewritten in a DOM-free way (using enzyme).
  • Loading branch information
ryota-ka committed May 7, 2020
1 parent f9b4a13 commit f7be660
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 2 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,6 @@
"compile": "npm run compile-cjs && npm run compile-es6",
"compile-cjs": "tsc --module commonjs --outDir ./lib/cjs",
"compile-es6": "echo 'TODO' : tsc --module es6 --outDir ./lib/es6",
"test": "$(npm bin)/mocha test/*.ts --require ts-node/register --recursive"
"test": "$(npm bin)/mocha test/*.ts test/*.tsx --require ts-node/register --recursive"
}
}
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export {ReactSource} from './ReactSource';
export {h} from './h';
export {incorporate} from './incorporate';
export {StreamRenderer} from './StreamRenderer';
export {default as jsxFactory} from './jsxFactory';
36 changes: 36 additions & 0 deletions src/jsxFactory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {createElement, ReactElement, ReactType} from 'react';
import {incorporate} from './incorporate';
export {Attributes} from 'react';

declare global {
namespace JSX {
interface IntrinsicAttributes {
sel?: string | symbol;
}
}
namespace React {
interface ClassAttributes<T> extends Attributes {
sel?: string | symbol;
}
}
}

type PropsExtensions = {
sel?: string | symbol;
}

function createIncorporatedElement<P = any>(
type: ReactType<P>,
props: P & PropsExtensions | null,
...children: Array<string | ReactElement<any>>
): ReactElement<P> {
if (!props || !props.sel) {
return createElement(type, props, ...children);
} else {
return createElement(incorporate(type), props, ...children);
}
}

export default {
createElement: createIncorporatedElement
}
84 changes: 84 additions & 0 deletions test/jsxFactory.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import * as React from 'react';
import * as Adapter from 'enzyme-adapter-react-16';
import * as Enzyme from 'enzyme';
import xs from 'xstream';
const assert = require('assert');
import {jsxFactory, h, ReactSource, makeCycleReactComponent} from '../src';

Enzyme.configure({adapter: new Adapter()});

const { shallow } = Enzyme;

describe('jsxFactory', function () {
it('w/ nothing', () => {
const wrapper = shallow(<h1></h1>);

assert.strictEqual(wrapper.find('h1').length, 1);
});

it('w/ text child', () => {
const wrapper = shallow(<h1>heading 1</h1>);

const h1 = wrapper.find('h1');
assert.strictEqual(h1.text(), 'heading 1');
});

it('w/ children array', () => {
const wrapper = shallow(
<section>
<h1>heading 1</h1>
<h2>heading 2</h2>
<h3>heading 3</h3>
</section>
);

const section = wrapper.find('section');
assert.strictEqual(section.children().length, 3);
});

it('w/ props', () => {
const wrapper = shallow(<section data-foo='bar' />);

assert(wrapper.exists('[data-foo="bar"]'));
});

it('w/ props and children', () => {
const wrapper = shallow(
<section data-foo="bar">
<h1>heading 1</h1>
<h2>heading 2</h2>
<h3>heading 3</h3>
</section>
);

const section = wrapper.first();
assert.strictEqual(section.length, 1);
assert(section.exists('[data-foo="bar"]'));
assert.deepStrictEqual(section.children().length, 3);
});

it('w/ className', () => {
const wrapper = shallow(<section className="foo" />);

assert(wrapper.hasClass('foo'));
});

it('renders functional component', () => {
const Test = () => <h1>Functional</h1>;
const wrapper = shallow(<Test />);

assert.strictEqual(wrapper.first().type(), 'h1');
});

it('renders class component', () => {
class Test extends React.Component {
render() {
return <h1>Class</h1>;
}
}

const wrapper = shallow(<Test />);

assert.strictEqual(wrapper.first().type(), 'h1');
});
});
4 changes: 3 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
"rootDir": "src/",
"outDir": "lib/cjs/",
"skipLibCheck": true,
"lib": ["dom", "es5", "scripthost", "es2015"]
"lib": ["dom", "es5", "scripthost", "es2015"],
"jsx": "react",
"jsxFactory": "jsxFactory.createElement"
},
"files": ["src/index.ts"]
}

0 comments on commit f7be660

Please sign in to comment.