How to test a component base on material ui? - javascript

I have the following component, that is build with https://material-ui-next.com/.
import React from 'react';
import { AppBar, Toolbar } from 'material-ui';
import { Typography } from 'material-ui';
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles';
import {lightBlue} from 'material-ui/colors';
const theme = createMuiTheme({
palette: {
primary: {
main:lightBlue['A700']
},
text: {
primary: '#fff',
}
},
});
const View = (props) => (
<MuiThemeProvider theme={theme}>
<AppBar position="static">
<Toolbar>
<Typography variant="title">
{props.title}
</Typography>
</Toolbar>
</AppBar>
</MuiThemeProvider>
);
export default View;
I am trying to write a test for it:
import React from 'react';
import { shallow } from 'enzyme';
import View from '../Views/View';
import { Typography } from 'material-ui';
it('renders', () => {
const wrapper = shallow(<View title='Welcome' />);
expect(wrapper.find('Typography').text()).toEqual('Welcome');
});
How to write a test for a component, that is using material-ui components? In the case above, I tried to figure out, if the component contains Welcome.
I read https://material-ui-next.com/guides/testing/, but it is not clear, how can I write a test.

UPD: API changed from shallow to mount
Did you tried to use their API described here?
Probably your test can look something like this:
import React from 'react';
import { createMount } from 'material-ui/test-utils';
import View from '../Views/View';
import { Typography } from 'material-ui';
it('renders', () => {
const mount = createMount();
const wrapper = mount(<View title='Welcome' />);
expect(wrapper.find('Typography').text()).toEqual('Welcome');
});

Related

React Native Error: The component for route must be a React component

I'm trying to create a basic setup for react navigation, but for some reason, when I go to view the project, I get a blank screen and an error in terminal that says:
Error: The component for route 'screens' must be a React component. For example:
import MyScreen from './MyScreen';
...
screens: MyScreen,
}
You can also use a navigator:
import MyNavigator from './MyNavigator';
...
screens: MyNavigator,
}
I've looked at other Stack Overflow solutions, but none of them seem to apply in my case, so, is there something else I'm doing wrong here?
My App.js (Also importing fonts here, but these worked, it seems to be an issue with the routing)
import React, {useState} from 'react';
import * as Font from 'expo-font';
import AppLoading from 'expo-app-loading';
import Navigator from './routes/homeStack';
const getFonts = () => Font.loadAsync({
'raleway-regular': require('./assets/fonts/Raleway-Regular.ttf'),
'raleway-bold': require('./assets/fonts/Raleway-Bold.ttf')
});
export default function App() {
const [fontsLoaded, setFontsLoaded] = useState(false);
if (fontsLoaded) {
return (
<Navigator />
);
} else {
return (
<AppLoading
startAsync= {getFonts}
onFinish= {()=> setFontsLoaded(true)}
onError= {()=> console.log('error')}
/>
);
}
}
homeStack.js
import { createStackNavigator } from 'react-navigation-stack';
import { createAppContainer } from 'react-navigation';
import Home from '../screens/home';
import Scanner from '../screens/scanner';
const screens = {
Home: {
screen: Home
},
Scanner: {
screen: Scanner
},
};
const HomeStack = createStackNavigator({screens});
export default createAppContainer(HomeStack);
home.js
import React from 'react';
import { StyleSheet, View, Text, } from 'react-native';
import { globalStyles } from '../styles/global';
export default function Home() {
return (
<View style={globalStyles.container}>
<Text style={globalStyles.titleText}>Home Screen</Text>
</View>
);
}
scanner.js
import React from 'react';
import { StyleSheet, View, Text } from 'react-native';
import { globalStyles } from '../styles/global';
export default function Scanner() {
return (
<View style={globalStyles.container}>
<Text>About Screen</Text>
</View>
);
}
My file directory
Any help would be much appreciated!
The video you are following along with is really old and probably not up to date anymore. Please follow the installation guides and then follow along this guide. That should get you up and running in minutes.

MUI createTheme in nextjs

I used material-UI version 4 for my project. I recently changed it to version 5.5.0. But createTheme does not work properly. None of the colors and settings used in the palette apply.
next: 11.0.0
react:17.0.2
mui : 5.5.0
theme.js
import { createTheme, responsiveFontSizes } from "#mui/material/styles";
import { deepPurple, amber } from "#mui/material/colors";
import palette from './palette';
import typography from './typography';
let theme = createTheme({
palette,
typography,
zIndex: {
appBar: 1200,
drawer: 1100
}
});
// const Theme = responsiveFontSizes(theme);
export default theme;
As you can see below I used ThemeProvider in _app.js, I put the document file in the github similar to the UI material example. Do I need to do anything else?
https://github.com/mui/material-ui/blob/master/examples/nextjs/pages/_document.js
_app.js
import React from "react";
import PropTypes from 'prop-types';
import Head from 'next/head';
import dynamic from 'next/dynamic';
import { ThemeProvider } from '#mui/styles';
import CssBaseline from '#mui/material/CssBaseline';
import { CacheProvider } from '#emotion/react';
import createEmotionCache from '../theme/createEmotionCache';
import theme from "../theme"
import { wrapper } from '../_redux/store';
import MenuTop from '../_components/Sessions/menu_top';
import Footer from '../_components/Sessions/footer';
import MenuIndex from '../_components/Sessions/menu_index';
import Header from '../_components/Sessions/header';
import Snackbar from '../_components/Sessions/Snackbar';
import "../styles/404.css";
import "../styles/index.css";
// Client-side cache, shared for the whole session of the user in the browser.
const clientSideEmotionCache = createEmotionCache();
function MyApp(props) {
const { Component, emotionCache = clientSideEmotionCache, pageProps } = props;
return (
<CacheProvider value={emotionCache}>
<Head>
</Head>
<ThemeProvider theme={theme}>
<Snackbar {...pageProps.alert} />
<MenuTop/>
<Header/>
<MenuIndex/>
{/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
<CssBaseline />
<div style={{ userSelect: "none" }}>
{/* <StylesProvider jss={jss}> */}
<Component {...pageProps} />
{/* </StylesProvider> */}
<Footer/>
</div>
</ThemeProvider>
</CacheProvider>
);
}
MyApp.propTypes = {
Component: PropTypes.elementType.isRequired,
emotionCache: PropTypes.object,
pageProps: PropTypes.object.isRequired,
};
export default wrapper.withRedux(MyApp);
You can try to remove the zIndex in the createTheme so the theme should be work.
let theme = createTheme({
palette,
typography
});

Where can we define the Theme for Material-UI in React

I am confused when setting styling for Material-UI based front-end.
Where does theme come from in the example code below and what are the effects of the theme?
import React from "react";
import Container from "#material-ui/core/Container";
const useStyles = makeStyles(theme => ({
root: {
height: "100%"
}
}));
const Sample = props => {
const classes = useStyles();
return (
<Container className={classes.root}/>
);
}
There is a provider of theme so called ThemeProvider
document of material-ui theming
more customized usage advanced theming
<ThemeProvider theme={outerTheme}>
<Checkbox defaultChecked />
<ThemeProvider theme={innerTheme}>
<Checkbox defaultChecked />
</ThemeProvider>
</ThemeProvider>
It provide the theme to the child components, we usually define this at the top level of the project.
Then you can access the Theme defined above via multiple ways
accessing-the-theme-in-a-component
For example, for classical component we have withTheme HOC
import { withTheme } from '#material-ui/core/styles';
function DeepChildRaw(props) {
return <span>{`spacing ${props.theme.spacing}`}</span>;
}
const DeepChild = withTheme(DeepChildRaw);
For functional component, we have useTheme hooks
import { useTheme } from '#material-ui/core/styles';
function DeepChild() {
const theme = useTheme();
return <span>{`spacing ${theme.spacing}`}</span>;
}
And you can use them inside makeStyles and createStyles as normal
import { makeStyles } from '#material-ui/core/styles';
const useStyles = makeStyles(theme => ({
root: {
width: theme.spacing(1);
}
}));
import { createStyles } from '#material-ui/core/styles';
const styles = (theme: Theme) => createStyles({
root: {
width: theme.spacing(1);
}
})

Taking input and outputing it Inside of an expansion Panel in React js

So I am trying to take a user input and output that through Material UI expansion panels this is currently what i have to do so. but im getting an error saying this.props.GitInput is not a function
import React, { Component } from 'react';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import RaisedButton from 'material-ui/RaisedButton';
import IdentificationField from './IdentificationField';
import DataGraph from './DataGraph';
import PropTypes from 'prop-types';
class AssociateIdentification extends Component {
constructor() {
super();
this.state = {
GitInput: '',
};
this.GitInput = this.GitInput.bind(this);
}
componentDidMount() {
if (this.props.id !== 0) {
this.GitInput();
}
}
componentDidUpdate(_, prevState) {
if (prevState.id !== this.state.id) {
this.GitInput();
}
}
GitInput() {
this.props.GitInput(this.state.id);
}
render() {
return (
<div>
<input type="text" onChange={this.handleSubmit} />
{this.state.GitInput}
</div>
);
}
}
export default (AssociateIdentification);
and I am outputing it like this on a seperate component.
import React from 'react';
import { MockGit } from './Constants';
import ExpansionPanelSummary from '#material-ui/core/ExpansionPanelSummary';
import ExpansionPanelDetails from '#material-ui/core/ExpansionPanelDetails';
import Typography from '#material-ui/core/Typography';
import ExpandMoreIcon from '#material-ui/icons/ExpandMore';
import ExpansionPanel from '#material-ui/core/ExpansionPanel';
import GitInput from './AssociateIdentification';
const GitData = () => {
return (
<ExpansionPanel>
<ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}>
<Typography> {MockGit} </Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<Typography>
{GitInput}
</Typography>
</ExpansionPanelDetails>
</ExpansionPanel>
);
};
export default (GitData);
I know this is fairly simple but I am struggling to get it to work.

Module build failed: Duplicate declaration

I'm using Ant Design Framework for my React project. But when importing components, it yells an error even though I haven't declared those components before.
ERROR:
Module build failed: Duplicate declaration "Icon"
Here is the code:
// App.js
import React from 'react';
import ReactDOM from 'react-dom';
import { FullSpinner } from "./Spinner"
class App extends React.Component {
render() {
return (<div>sdkfjsdf</div>)
}
}
export default App
// Spinner.js
import { Spin, Icon } from 'antd';
import React from 'react'
import {Icon, Spin} from 'antd';
const antIcon = () => <Icon type="loading" style={{ fontSize: 24 }} spin />;
export const FullSpinner = () => <Spin indicator={antIcon} />
You have imported Icon component multiple times.
// Spinner.js
import { Spin, Icon } from 'antd';
import React from 'react'
import {Icon, Spin} from 'antd'; <- Duplicate
const antIcon = () => <Icon type="loading" style={{ fontSize: 24 }} spin />;
export const FullSpinner = () => <Spin indicator={antIcon} />
Try after removing import { Spin, Icon } from 'antd'; from Spinner.js
Your Spinner.js file is importing the Spin and Icon twice from the antd module. You can safely remove one of those lines.
// Spinner.js
import React from 'react'
import {Icon, Spin} from 'antd';
const antIcon = () => <Icon type="loading" style={{ fontSize: 24 }} spin />;
export const FullSpinner = () => <Spin indicator={antIcon} />

Categories

Resources