
import React from '../../src/May';
import ReactTestUtils from "../../lib/ReactTestUtils";

// import React from "../../dist/ReactANU";
// var ReactDOM = React;
// var ReactTestUtils = {
//   renderIntoDocument: function (element) {
//     var div = document.createElement("div");
//     return React.render(element, div);
//   }
// };
var Redux = require("redux");
var ReactRedux = require("react-redux");

describe("Redux", function () {
	// this.timeout(200000);
	// before(async () => {
	//   await beforeHook();
	// });
	// after(async () => {
	//   await afterHook(false);
	// });
	var body = document.body,
		div;
	beforeEach(function () {
		div = document.createElement("div");
		body.appendChild(div);
	});
	afterEach(function () {
		body.removeChild(div);
	});
	it("Counter", async () => {
		class Counter extends React.Component {
			render() {
				return (
					<div>
						<h1 ref="value">{this.props.value}</h1>
						<button ref="a" onClick={this.props.onIncrement}>
							+
            </button>&nbsp;
            <button ref="b" onClick={this.props.onDecrement}>
							-
            </button>
					</div>
				);
			}
		}

		const reducer = (state = 0, action) => {
			switch (action.type) {
				case "INCREMENT":
					return state + 1;
				case "DECREMENT":
					return state - 1;
				default:
					return state;
			}
		};

		const store = Redux.createStore(reducer);
		function onIncrement() {
			store.dispatch({ type: "INCREMENT" });
		}
		function onDecrement() {
			store.dispatch({ type: "DECREMENT" });
		}

		const render = () => {
			return ReactDOM.render(
				<Counter
					value={store.getState()}
					onIncrement={onIncrement}
					onDecrement={onDecrement}
				/>,
				div
			);
		};

		var s = render();
		store.subscribe(render);
		expect(s.refs.value.innerHTML).toBe("0");
		expect(s.refs.a.tagName).toBe("BUTTON");
		ReactTestUtils.Simulate.click(s.refs.a);

		expect(s.refs.value.innerHTML).toBe("10");//1
		// await browser
		// 	.click(s.refs.a)
		// 	.pause(100)
		// 	.$apply();
		// expect(s.refs.value.innerHTML).toBe("2");
		// await browser
		// 	.click(s.refs.b)
		// 	.pause(100)
		// 	.$apply();
		// expect(s.refs.value.innerHTML).toBe("1");
	});
	/*it("TreeView", async () => {
	 
	  var idArr = ["tree1", "tree2", "tree3", "tree4", "tree5", "tree6", "tree7"];
	  var combineReducers = Redux.combineReducers;
	  var Provider = ReactRedux.Provider;
	  var connect = ReactRedux.connect;
	  var createStore = Redux.createStore;
	  function generateTree() {
		let tree = {
		  0: {
			id: 0,
			counter: 0,
			childIds: []
		  }
		};
  
		for (let i = 1; i < 3; i++) {
		  let parentId = 0; //Math.floor(Math.pow(Math.random(), 2) * i)
		  tree[i] = {
			id: i,
			counter: 0,
			childIds: []
		  };
		  tree[parentId].childIds.push(i);
		}
  
		return tree;
	  }
	  const INCREMENT = "INCREMENT";
	  const CREATE_NODE = "CREATE_NODE";
	  const DELETE_NODE = "DELETE_NODE";
	  const ADD_CHILD = "ADD_CHILD";
	  const REMOVE_CHILD = "REMOVE_CHILD";
  
	  const increment = nodeId => ({
		type: INCREMENT,
		nodeId
	  });
  
	  let nextId = 0;
	  const createNode = () => ({
		type: CREATE_NODE,
		nodeId: `new_${nextId++}`
	  });
  
	  const deleteNode = nodeId => ({
		type: DELETE_NODE,
		nodeId
	  });
  
	  const addChild = (nodeId, childId) => ({
		type: ADD_CHILD,
		nodeId,
		childId
	  });
  
	  const removeChild = (nodeId, childId) => ({
		type: REMOVE_CHILD,
		nodeId,
		childId
	  });
	  var actions = {
		increment,
		createNode,
		deleteNode,
		addChild,
		removeChild
	  };
	  class Node extends React.Component {
		constructor(props) {
		  super(props);
		  this.handleIncrementClick = this.handleIncrementClick.bind(this);
		  this.handleAddChildClick = this.handleAddChildClick.bind(this);
		  this.handleRemoveClick = this.handleRemoveClick.bind(this);
		  this.renderChild = this.renderChild.bind(this);
		}
		handleIncrementClick() {
		  const { increment, id } = this.props;
		  increment(id);
		}
  
		handleAddChildClick(e) {
		  e.preventDefault();
  
		  const { addChild, createNode, id } = this.props;
		  const childId = createNode().nodeId;
		  addChild(id, childId);
		}
  
		handleRemoveClick(e) {
		  e.preventDefault();
  
		  const { removeChild, deleteNode, parentId, id } = this.props;
		  removeChild(parentId, id);
		  deleteNode(id);
		}
  
		renderChild(childId) {
		  const { id } = this.props;
		  return (
			<li key={childId}>
			  <ConnectedNode id={childId} parentId={id} />
			</li>
		  );
		}
  
		render() {
		  const { counter, parentId, childIds } = this.props;
		  return (
			<div>
			  Counter: {counter}{" "}
			  <button onClick={this.handleIncrementClick}>+</button>{" "}
			  {typeof parentId !== "undefined" && (
				<a
				  href="#"
				  id={idArr.shift()}
				  onClick={this.handleRemoveClick}
				  className="remove"
				  style={{ color: "lightgray", textDecoration: "none" }}
				>
				  ×
				</a>
			  )}
			  <ul>
				{childIds.map(this.renderChild)}
				<li key="add">
				  <a
					href="#"
					id={idArr.shift()}
					onClick={this.handleAddChildClick}
					className="add"
				  >
					Add child
				  </a>
				</li>
			  </ul>
			</div>
		  );
		}
	  }
  
	  function mapStateToProps(state, ownProps) {
		return state[ownProps.id];
	  }
  
	  const ConnectedNode = connect(mapStateToProps, actions)(Node);
  
	  //import { INCREMENT, ADD_CHILD, REMOVE_CHILD, CREATE_NODE, DELETE_NODE } from '../actions'
  
	  const childIds = (state, action) => {
		switch (action.type) {
		  case ADD_CHILD:
			return [...state, action.childId];
		  case REMOVE_CHILD:
			return state.filter(id => id !== action.childId);
		  default:
			return state;
		}
	  };
  
	  const node = (state, action) => {
		switch (action.type) {
		  case CREATE_NODE:
			return {
			  id: action.nodeId,
			  counter: 0,
			  childIds: []
			};
		  case INCREMENT:
			return {
			  ...state,
			  counter: state.counter + 1
			};
		  case ADD_CHILD:
		  case REMOVE_CHILD:
			return {
			  ...state,
			  childIds: childIds(state.childIds, action)
			};
		  default:
			return state;
		}
	  };
  
	  const getAllDescendantIds = (state, nodeId) =>
		state[nodeId].childIds.reduce(
		  (acc, childId) => [
			...acc,
			childId,
			...getAllDescendantIds(state, childId)
		  ],
		  []
		);
  
	  const deleteMany = (state, ids) => {
		state = { ...state };
		ids.forEach(id => delete state[id]);
		return state;
	  };
  
	  function reducers(state = {}, action) {
		const { nodeId } = action;
		if (typeof nodeId === "undefined") {
		  return state;
		}
  
		if (action.type === DELETE_NODE) {
		  const descendantIds = getAllDescendantIds(state, nodeId);
		  return deleteMany(state, [nodeId, ...descendantIds]);
		}
  
		return {
		  ...state,
		  [nodeId]: node(state[nodeId], action)
		};
	  }
  
	  const tree = generateTree();
  
	  const store = createStore(reducers, tree);
	  var s = ReactDOM.render(
		<Provider store={store}>
		  <ConnectedNode id={0} />
		</Provider>,
		div
	  );
	//   var ass = div.getElementsByTagName("a");
	//   expect(ass.length).toBe(5);
	//   var el = ass[1];
  
	//   await browser
	// 	.click(el)
	// 	.pause(200)
	// 	.$apply();
  
	//   expect(ass.length).toBe(el.className === "add" ? 7 : 5);
	//   await browser
	// 	.click(ass[4])
	// 	.pause(100)
	// 	.$apply();
  
	//   expect(ass.length).toBe(5);
	});*/
});
