function TestNode.new(Y,Q,J,p)p=p or TestEnum.NodeModifier.None local H={plan=Y;phrase=Q,type=J;modifier=p,children={},callback=nil;parent=nil}H.environment=newEnvironment(H,Y.extraEnvironment)return setmetatable(H,TestNode)end local function Y(Y,Q,J)if Q and(J==nil or J==TestEnum.NodeModifier.None)then if Y:match(Q)then return TestEnum.NodeModifier.Focus else return TestEnum.NodeModifier.Skip end end return J end function TestNode.addChild(H,Q,J,p)if J==TestEnum.NodeType.It then for Y,J in pairs(H.children)do if J.phrase==Q then error("\068\117\112\108\105\099\097\116\101 \105\116 \098\108\111\099\107 \102\111\117\110\100\058 "..J:getFullName())end end end local V=H:getFullName()..(" "..Q)p=Y(V,H.plan.testNamePattern,p)local n=TestNode.new(H.plan,Q,J,p)n.parent=H table.insert(H.children,n)return n end

function TestNode.new(plan, phrase, nodeType, nodeModifier)
	nodeModifier = nodeModifier or TestEnum.NodeModifier.None

	local node = {
		plan = plan,
		phrase = phrase,
		type = nodeType,
		modifier = nodeModifier,
		children = {},
		callback = nil,
		parent = nil,
	}

	node.environment = newEnvironment(node, plan.extraEnvironment)
	return setmetatable(node, TestNode)
end

local function getModifier(name, pattern, modifier)
	if pattern and (modifier == nil or modifier == TestEnum.NodeModifier.None) then
		if name:match(pattern) then
			return TestEnum.NodeModifier.Focus
		else
			return TestEnum.NodeModifier.Skip
		end
	end
	return modifier
end

function TestNode:addChild(phrase, nodeType, nodeModifier)
	if nodeType == TestEnum.NodeType.It then
		for _, child in pairs(self.children) do
			if child.phrase == phrase then
				error("Duplicate it block found: " .. child:getFullName())
			end
		end
	end

	local childName = self:getFullName() .. " " .. phrase
	nodeModifier = getModifier(childName, self.plan.testNamePattern, nodeModifier)
	local child = TestNode.new(self.plan, phrase, nodeType, nodeModifier)
	child.parent = self
	table.insert(self.children, child)
	return child
end
