<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: madhur Saluja</title>
    <description>The latest articles on DEV Community by madhur Saluja (@msaluja).</description>
    <link>https://dev.to/msaluja</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2037955%2F4b809aa9-d24e-46c0-8faf-a9cd2ce68c31.png</url>
      <title>DEV Community: madhur Saluja</title>
      <link>https://dev.to/msaluja</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/msaluja"/>
    <language>en</language>
    <item>
      <title>Final Post Reflection</title>
      <dc:creator>madhur Saluja</dc:creator>
      <pubDate>Thu, 12 Dec 2024 04:43:28 +0000</pubDate>
      <link>https://dev.to/msaluja/final-post-reflection-57jm</link>
      <guid>https://dev.to/msaluja/final-post-reflection-57jm</guid>
      <description>&lt;p&gt;As this project concludes, I can confidently say that the journey has been transformative both in terms of my technical skills and personal growth. Working individually on this project taught me to handle challenges head-on and pushed me to explore areas outside my comfort zone. Here's a detailed account of what I accomplished, how I tackled obstacles, and what I learned along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Achieving My Goals
&lt;/h2&gt;

&lt;p&gt;At the beginning of this course, my primary goal was to contribute meaningfully to a real-world project while improving my skills in front-end development and testing. Looking back, I’m proud of how far I’ve come. Not only did I manage to contribute new features and improvements to the codebase, but I also learned how to engage effectively with the open-source community.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Adding New Features
&lt;/h4&gt;

&lt;p&gt;I implemented a feature in the FeaturesSection component to allow dynamic rendering of feature cards. This required deep diving into React best practices and integrating Framer Motion for animations.&lt;/p&gt;

&lt;p&gt;Ensuring the feature aligned with the existing CSS aesthetic was a significant focus. I spent hours refining styles to maintain the visual appeal and cohesiveness of the website. Matching the existing design standards was challenging but rewarding, as the final result blended seamlessly with the original.&lt;/p&gt;

&lt;h3&gt;
  
  
  Styling Challenges
&lt;/h3&gt;

&lt;p&gt;Adapting my code to fit the established styling conventions of the project was one of the most time-intensive tasks. The project had intricate and polished CSS, and ensuring my additions met this high standard required meticulous attention to detail. I experimented with utility-first CSS approaches and iterated multiple times until it looked perfect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unit Testing Implementation
&lt;/h2&gt;

&lt;p&gt;I wrote unit tests for the following components:&lt;/p&gt;

&lt;p&gt;BackgroundGradient: Verified child rendering and conditional animation styles.&lt;/p&gt;

&lt;p&gt;CardHoverEffect: Ensured all props were rendered correctly and hover interactions worked as expected.&lt;/p&gt;

&lt;p&gt;FeaturesSection: Tested responsiveness, card rendering, and empty state scenarios.&lt;/p&gt;

&lt;p&gt;Setting up Jest and React Testing Library was a foundational task. This included configuring the test environment and writing meaningful, robust tests. Testing helped identify edge cases and improved overall code reliability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Community Engagement
&lt;/h2&gt;

&lt;p&gt;One of the most valuable aspects of this journey was learning to engage with the open-source community. I reached out to the project maintainer on Discord to clarify requirements and discuss design decisions. This interaction not only provided insights into the project’s vision but also boosted my confidence in discussing technical ideas with experienced developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges and How I Overcame Them
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Adapting to Established Code Standards
&lt;/h4&gt;

&lt;p&gt;Initially, understanding and adapting to the existing codebase and styling was daunting. I overcame this by thoroughly analyzing the code, experimenting locally, and referring to documentation.&lt;/p&gt;

&lt;h4&gt;
  
  
  Learning Communication Skills
&lt;/h4&gt;

&lt;p&gt;As someone new to community engagement, I had to learn how to ask concise yet meaningful questions. By observing community norms and being open to feedback, I improved significantly in this area.&lt;/p&gt;

&lt;h4&gt;
  
  
  Testing Complex Components
&lt;/h4&gt;

&lt;p&gt;Writing unit tests for components with animations and dynamic states was challenging. For instance, ensuring the FeaturesSection responded to empty states and viewport changes required creative use of testing libraries.&lt;/p&gt;

&lt;p&gt;Issue Links- &lt;br&gt;
&lt;a href="https://github.com/daabChingrii/website/issues/15" rel="noopener noreferrer"&gt;Issue1&lt;/a&gt; &lt;br&gt;
&lt;a href="https://github.com/daabChingrii/website/issues/34" rel="noopener noreferrer"&gt;Issue2&lt;/a&gt;&lt;br&gt;
PR Links- &lt;br&gt;
&lt;a href="https://github.com/daabChingrii/website/pull/33" rel="noopener noreferrer"&gt;PR1&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/daabChingrii/website/pull/35" rel="noopener noreferrer"&gt;PR2&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;p&gt;Importance of Standards: Adhering to high CSS and code quality standards improved my attention to detail and ability to deliver polished work.&lt;/p&gt;

&lt;p&gt;Community Interaction: Asking the right questions and collaborating with maintainers is as crucial as writing good code.&lt;/p&gt;

&lt;p&gt;Test-Driven Development: Writing tests not only identifies potential bugs but also provides clarity on expected functionality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Moving Forward
&lt;/h2&gt;

&lt;p&gt;This course and project solidified my technical foundation and introduced me to real-world development processes. The decision to take this course was one of the best I’ve made. The lessons learned and skills gained will undoubtedly help me in my career as a software engineer. From coding and testing to communicating effectively, this experience has been a cornerstone of my growth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;I’m incredibly proud of the work I accomplished, from implementing new features to matching the project’s aesthetic, writing comprehensive tests, and engaging with the community. This journey has been filled with challenges and learning opportunities, and I’ll carry these experiences forward as I continue to grow as a developer.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Week 2 Progress Update</title>
      <dc:creator>madhur Saluja</dc:creator>
      <pubDate>Tue, 10 Dec 2024 07:14:13 +0000</pubDate>
      <link>https://dev.to/msaluja/week-2-progress-update-1fn2</link>
      <guid>https://dev.to/msaluja/week-2-progress-update-1fn2</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This week has been both challenging and productive as I continued working on improving and contributing to the project. Here, I’ll share my progress, what I’ve accomplished, the challenges I faced, and how I plan to adjust to meet my goals by the end of the term.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Have Done So Far
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Focused on Matching Aesthetic Standards:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A significant portion of this week was spent ensuring that the CSS styling of the components aligns perfectly with the current aesthetics of the website. &lt;/li&gt;
&lt;li&gt;Matching the website’s established design system required careful attention to detail and iterative adjustments.&lt;/li&gt;
&lt;li&gt;This task was more time-consuming than expected, but it was essential to maintain the visual consistency of the project.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Started Writing Unit Tests:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I began creating unit tests for critical components of the project using Jest and React Testing Library.&lt;/li&gt;
&lt;li&gt;My main focus has been on components like &lt;code&gt;BackgroundGradient&lt;/code&gt;, &lt;code&gt;CardHoverEffect&lt;/code&gt;, and &lt;code&gt;FeaturesSection&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;These tests ensure that the components behave as expected under various scenarios, such as rendering correctly, responding to user interactions, and handling edge cases.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Collaboration with the Maintainer:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I reached out to the project maintainer on Discord to discuss best practices and clarify doubts about the project structure.&lt;/li&gt;
&lt;li&gt;This conversation helped me understand the project’s testing and coding standards better and aligned my contributions with the maintainer's expectations.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Challenges Faced
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Matching CSS Standards:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adhering to the existing design system took more time than anticipated due to the complexity of the website’s current styling and animations.&lt;/li&gt;
&lt;li&gt;Some minor discrepancies required in-depth research and experimentation with CSS and animations to achieve the desired look and feel.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Writing Comprehensive Unit Tests:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating detailed test cases that cover all edge scenarios was challenging, particularly for components with conditional rendering and animations.&lt;/li&gt;
&lt;li&gt;Understanding how animations and event handlers integrate into the testing framework required additional research.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  What I Have Figured Out
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;CSS Research and Debugging:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I have developed a better understanding of how to debug and refine CSS to achieve pixel-perfect alignment with existing styles.&lt;/li&gt;
&lt;li&gt;Experimenting with various CSS properties and consulting design resources helped me resolve many styling challenges.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Unit Testing Workflow:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After some trial and error, I successfully set up Jest and React Testing Library for the project.&lt;/li&gt;
&lt;li&gt;I now have a clear framework for structuring test cases and ensuring all essential behaviors are covered.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Adjusting to Meet My Goals
&lt;/h2&gt;

&lt;p&gt;To stay on track and achieve my goals for this project, I will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dedicate specific time blocks to focus on completing the unit tests.&lt;/li&gt;
&lt;li&gt;Monitor my progress closely and make adjustments to my plan if needed.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This week has been an excellent opportunity to learn and grow while tackling real-world challenges in a collaborative project. While progress has been slower than anticipated in some areas, I am confident that the foundation I’ve built will allow me to move forward effectively. &lt;/p&gt;

&lt;p&gt;I look forward to completing the unit tests and ensuring that my contributions align perfectly with the project’s standards.&lt;/p&gt;




&lt;p&gt;Stay tuned for more updates next week as I aim to wrap up the unit testing phase and explore additional opportunities to enhance the project!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Planning Document for Issue #15: Features Section Improvement</title>
      <dc:creator>madhur Saluja</dc:creator>
      <pubDate>Tue, 10 Dec 2024 00:07:14 +0000</pubDate>
      <link>https://dev.to/msaluja/planning-document-for-issue-15-features-section-improvement-54cj</link>
      <guid>https://dev.to/msaluja/planning-document-for-issue-15-features-section-improvement-54cj</guid>
      <description>&lt;h2&gt;
  
  
  Motivation and Planning
&lt;/h2&gt;

&lt;p&gt;(edit- I just realized that this blog for planning has been siting in draft from over a week whereas I thought its already posted. Sorry for the late post)&lt;/p&gt;

&lt;p&gt;As part of my open-source journey, I decided to work on &lt;a href="https://github.com/daabChingrii/website/issues/15" rel="noopener noreferrer"&gt;Issue #15&lt;/a&gt; in the DaabChingrii project. This issue focused on creating, designing and improving the &lt;strong&gt;Features Section&lt;/strong&gt;, ensuring it aligned seamlessly with the rest of the website while incorporating modern animation and styling practices.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why This Issue?
&lt;/h3&gt;

&lt;p&gt;I specifically chose this issue because it offered a fresh challenge—something I had not attempted before in my open-source contributions. The task required me to learn &lt;strong&gt;Tailwind CSS&lt;/strong&gt;, &lt;strong&gt;Framer Motion&lt;/strong&gt;, and delve into the project's structure. It was a unique opportunity to expand my skillset and contribute meaningful changes to a live project and learning a new Styling tool like Tailwind will also contribute to resume as I have not been to much active in front-end development lately.&lt;/p&gt;




&lt;h3&gt;
  
  
  Steps I Took
&lt;/h3&gt;

&lt;p&gt;The process involved multiple phases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Understanding the Project&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The project structure was initially unfamiliar, and I spent time analyzing and comprehending the file organization, component hierarchy, and Tailwind setup.&lt;/li&gt;
&lt;li&gt;I engaged in discussions within the project's Discord channel to clarify doubts about the existing structure and requirements even before officially asking to assign the issue and after getting assigned then I realized that there was conversation of issue page itself due to which I uploaded the final work screenshot there. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Learning the Tools and Technologies&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I had limited to no experience with &lt;strong&gt;Tailwind CSS&lt;/strong&gt; and &lt;strong&gt;Framer Motion&lt;/strong&gt;, so I dedicated time to exploring Tailwind's documentation and experimenting with its utilities for creating responsive layouts and animations.&lt;/li&gt;
&lt;li&gt;Framer Motion's animation principles, especially creating dynamic hover effects and viewport transitions, were new and exciting challenges.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Planning the Solution&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I spent time brainstorming ideas for the redesign. I carefully evaluated various design elements and animation effects to maintain consistency with the project's aesthetic.&lt;/li&gt;
&lt;li&gt;I also researched best practices for accessibility and performance optimization.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Reflection and Next Steps:
&lt;/h3&gt;

&lt;p&gt;I believe that, this issue will prove to be a valuable learning experience. It not only deepened my technical understanding but also enhanced my ability to contribute effectively in an open-source environment. &lt;/p&gt;




&lt;p&gt;This work has until now has been both a challenge and a rewarding experience, and I look forward to continuing my contributions to the DaabChingrii community!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Tackling Issue-164: Enhancing VoiceService Tests in React-Chatbotify</title>
      <dc:creator>madhur Saluja</dc:creator>
      <pubDate>Mon, 02 Dec 2024 01:44:22 +0000</pubDate>
      <link>https://dev.to/msaluja/tackling-issue-164-enhancing-voiceservice-tests-in-react-chatbotify-4gh3</link>
      <guid>https://dev.to/msaluja/tackling-issue-164-enhancing-voiceservice-tests-in-react-chatbotify-4gh3</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Working on open-source projects often presents unique challenges, and tackling &lt;strong&gt;Issue-164&lt;/strong&gt; in the &lt;a href="https://github.com/tjtanjin/react-chatbotify/issues/164" rel="noopener noreferrer"&gt;React-Chatbotify repository&lt;/a&gt; was no exception. The issue involved enhancing and structuring the test coverage for the &lt;code&gt;VoiceService&lt;/code&gt; component—a feature that supports both speech recognition and audio recording.&lt;/p&gt;

&lt;p&gt;This was my first time testing a voice component with such diverse functionality, and it came with its own learning curve. From understanding someone else's codebase to adapting to their development practices, this experience was both challenging and rewarding.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Journey
&lt;/h2&gt;

&lt;p&gt;When I first delved into the codebase, I faced the inevitable hurdle of unfamiliarity. Navigating through the &lt;code&gt;VoiceService&lt;/code&gt; component, which combines two distinct functionalities (speech recognition and audio recording), felt overwhelming at first. But as I progressed through my open-source development course, I noticed a significant improvement in how I approached these challenges. By the end of the course, I found myself far better equipped to comprehend and work with code written by others.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Made This Task Unique
&lt;/h3&gt;

&lt;p&gt;The task required creating distinct test cases for two separate functionalities within &lt;code&gt;VoiceService&lt;/code&gt;: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Speech Recognition:&lt;/strong&gt; Ensuring that the component behaves as expected when using &lt;code&gt;SpeechRecognition&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audio Recording:&lt;/strong&gt; Testing the functionality related to recording audio via the &lt;code&gt;MediaRecorder&lt;/code&gt; API.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Testing a voice component is inherently complex due to dependencies on browser-specific APIs, real-time user input, and error handling scenarios such as microphone access denial. Additionally, mocking these APIs for a controlled testing environment added another layer of complexity.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Solution
&lt;/h3&gt;

&lt;p&gt;In the &lt;a href="https://github.com/tjtanjin/react-chatbotify/pull/279" rel="noopener noreferrer"&gt;Pull Request #279&lt;/a&gt;, I implemented the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Separate Test Cases:&lt;/strong&gt; Clearly distinguished between test cases for &lt;code&gt;SpeechRecognition&lt;/code&gt; and &lt;code&gt;MediaRecorder&lt;/code&gt; functionality to improve clarity and maintainability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced Mocks:&lt;/strong&gt; Mocked browser-specific APIs like &lt;code&gt;navigator.mediaDevices.getUserMedia&lt;/code&gt; and &lt;code&gt;SpeechRecognition&lt;/code&gt; to simulate real-world scenarios.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error Handling Tests:&lt;/strong&gt; Validated how the system responds to common errors, such as microphone access denial or unsupported browser features.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edge Case Coverage:&lt;/strong&gt; Included tests for various settings, such as language configuration, timeout behaviors, and user actions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each test ensured that the &lt;code&gt;VoiceService&lt;/code&gt; handled the respective functionalities gracefully, even in adverse scenarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges and Growth
&lt;/h2&gt;

&lt;p&gt;This task wasn't just about writing tests—it was about growing as a developer. Testing a voice component pushed me to think beyond conventional test cases and consider user scenarios that are often unpredictable. More importantly, it reinforced the importance of writing robust and meaningful tests in a collaborative environment.&lt;/p&gt;

&lt;p&gt;By the end of this task, I felt a significant boost in confidence. I had effectively solved a real-world problem in someone else's codebase—a milestone in my journey as an open-source contributor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reflections
&lt;/h2&gt;

&lt;p&gt;Thanks to the structured learning from my open-source development course, the process of understanding and contributing to unfamiliar codebases has become smoother. While it still demands effort and patience, I now have a systematic approach to tackling such tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Acknowledgments
&lt;/h2&gt;

&lt;p&gt;I'm incredibly grateful for the opportunity to work on this issue and contribute to the React-Chatbotify repository. It was an enriching experience that deepened my understanding of testing and open-source collaboration.&lt;/p&gt;

&lt;p&gt;For more details, check out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/tjtanjin/react-chatbotify/issues/164" rel="noopener noreferrer"&gt;Issue #164&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tjtanjin/react-chatbotify/pull/279" rel="noopener noreferrer"&gt;Pull Request #279&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Contributing to open-source projects has been one of the most fulfilling parts of my journey as a developer. I look forward to solving more challenges and learning from the vibrant open-source community.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Madhur Saluja&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Debugging and Fixing a Complex Jest Test Case in React</title>
      <dc:creator>madhur Saluja</dc:creator>
      <pubDate>Thu, 28 Nov 2024 05:38:31 +0000</pubDate>
      <link>https://dev.to/msaluja/debugging-and-fixing-a-complex-jest-test-case-in-react-aok</link>
      <guid>https://dev.to/msaluja/debugging-and-fixing-a-complex-jest-test-case-in-react-aok</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Hi, So Recently, I was working on fixing a Jest test case for a React component. While I had some knowledge about testing, this task proved to be a steep learning curve. The issue involved a &lt;code&gt;ChatMessagePrompt&lt;/code&gt; component with multiple contexts and dynamic behaviors. What made it more challenging was my lack of prior experience with testing such complex components using Jest.&lt;/p&gt;

&lt;p&gt;In this blog, I'll share the challenges I faced, how I debugged the issue, and the eventual solution. If you're new to Jest or testing complex components, I hope this post will be helpful for you!&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;ChatMessagePrompt&lt;/code&gt; component provides users with a "scroll to bottom" prompt when there are unread messages. It relies on multiple React contexts (&lt;code&gt;BotRefsContext&lt;/code&gt;, &lt;code&gt;BotStatesContext&lt;/code&gt;, &lt;code&gt;SettingsContext&lt;/code&gt;, and &lt;code&gt;StylesContext&lt;/code&gt;) for its functionality.&lt;/p&gt;

&lt;p&gt;When running the test file, one specific test consistently failed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;FAIL __tests__/components/ChatBotBody/ChatMessagePrompt.test.tsx
ChatMessagePrompt Component
    ✓ renders with the correct message prompt text
    ✕ applies visible class when conditions are met
    ✓ applies hidden class when conditions are not met
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The error message indicated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Expected the element to have class:
  rcb-message-prompt-container visible
Received:
  rcb-message-prompt-container hidden
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Challenges Faced
&lt;/h2&gt;

&lt;p&gt;Here are the main challenges I encountered:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Dynamic Context Mocks&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The component relied heavily on context values. Some tests required &lt;code&gt;unreadCount&lt;/code&gt; and &lt;code&gt;isScrolling&lt;/code&gt; values to change dynamically, which wasn't happening in my initial implementation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;State Contamination Between Tests&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;unreadCount&lt;/code&gt; and &lt;code&gt;isScrolling&lt;/code&gt; were global mock variables, leading to cross-test state contamination.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;CSS Class Dependencies&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The visibility of the component depended on CSS classes, and Jest's handling of CSS can sometimes be tricky.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;JSDOM Limitations&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;scrollToBottom&lt;/code&gt; function in the component used &lt;code&gt;window.scrollTo&lt;/code&gt;, which isn't implemented by JSDOM.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Lack of Jest Expertise&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I was unfamiliar with advanced mocking techniques in Jest, such as dynamically returning mock values.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;After hours of debugging and research, here's how I solved the issue:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Dynamic Context Mocks
&lt;/h3&gt;

&lt;p&gt;Instead of using global variables for mocking &lt;code&gt;unreadCount&lt;/code&gt; and &lt;code&gt;isScrolling&lt;/code&gt;, I moved to dynamic mocking within each test. This allowed me to configure the mock values independently for every test.&lt;/p&gt;

&lt;h4&gt;
  
  
  Updated Code:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../../../src/context/BotStatesContext&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;useBotStatesContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;

&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;applies visible class when conditions are met&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;useBotStatesContext&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Mock&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;mockReturnValue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;unreadCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;isScrolling&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;setIsScrolling&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ChatMessagePrompt&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;messagePrompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Scroll to new messages&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;messagePrompt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentElement&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rcb-message-prompt-container visible&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  2. Cleaning Up Between Tests
&lt;/h3&gt;

&lt;p&gt;I ensured all timers and mock states were reset after each test to avoid cross-test contamination. Here's how I achieved that:&lt;/p&gt;

&lt;h4&gt;
  
  
  Updated Code:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;afterEach&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clearAllMocks&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;runOnlyPendingTimers&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useRealTimers&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  3. Mocking &lt;code&gt;window.scrollTo&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;To handle the &lt;code&gt;window.scrollTo&lt;/code&gt; issue, I mocked it globally in my test setup:&lt;/p&gt;

&lt;h4&gt;
  
  
  Updated Code:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;beforeAll&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;scrollTo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="na"&gt;writable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  4. Debugging CSS Class Issues
&lt;/h3&gt;

&lt;p&gt;I verified that Jest's CSS mocking was correctly configured in the &lt;code&gt;jest.config.js&lt;/code&gt; file. Here's the relevant snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"moduleNameMapper"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"\.(css|less|scss|sass)$"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"identity-obj-proxy"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensured that CSS classes like &lt;code&gt;visible&lt;/code&gt; and &lt;code&gt;hidden&lt;/code&gt; were correctly mocked and recognized in tests.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. Using Proper Timer Management
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;scrollToBottom&lt;/code&gt; function used animations (&lt;code&gt;requestAnimationFrame&lt;/code&gt;) and timers. I ensured Jest's fake timers simulated this behavior accurately:&lt;/p&gt;

&lt;h4&gt;
  
  
  Updated Code:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;advanceTimersByTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Simulate the scrolling duration&lt;/span&gt;
&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mockSetIsScrolling&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;This experience taught me a lot about Jest and testing React components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to dynamically mock context values.&lt;/li&gt;
&lt;li&gt;The importance of isolating test states.&lt;/li&gt;
&lt;li&gt;Handling JSDOM limitations with mocks.&lt;/li&gt;
&lt;li&gt;Debugging CSS-related issues in Jest.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's the final takeaway: testing complex components isn't just about writing tests but also understanding how the component interacts with its dependencies.&lt;/p&gt;

&lt;p&gt;If you're working on a similar problem, don't give up! Testing can be tricky, but it's also incredibly rewarding.&lt;/p&gt;




&lt;h2&gt;
  
  
  PR Generated
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/tjtanjin/react-chatbotify/pull/278" rel="noopener noreferrer"&gt;https://github.com/tjtanjin/react-chatbotify/pull/278&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Acknowledgments
&lt;/h2&gt;

&lt;p&gt;Although I solved this problem on my own, I want to thank the incredible testing and React communities for their resources and discussions that guided me along the way.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

&lt;p&gt;— Madhur&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Completing Lab 9 - Releasing Code Complexity Pro</title>
      <dc:creator>madhur Saluja</dc:creator>
      <pubDate>Thu, 28 Nov 2024 03:26:52 +0000</pubDate>
      <link>https://dev.to/msaluja/completing-lab-9-releasing-code-complexity-pro-477k</link>
      <guid>https://dev.to/msaluja/completing-lab-9-releasing-code-complexity-pro-477k</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Releasing software is an art that goes beyond writing good code—it’s about making your tool accessible, easy to install, and user-friendly. In Lab 9, I worked alone to finalize the release of &lt;strong&gt;Code Complexity Pro&lt;/strong&gt;, a Python command-line tool for analyzing code complexity using Groq’s LLM API. This blog walks you through the release process, the challenges I faced, and how I overcame them.&lt;/p&gt;




&lt;h2&gt;
  
  
  Choosing Tools and Registry
&lt;/h2&gt;

&lt;p&gt;I chose the following tools for the release:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Package Manager&lt;/strong&gt;: Python’s &lt;code&gt;setuptools&lt;/code&gt; for building the package and &lt;code&gt;twine&lt;/code&gt; for uploading it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Registry&lt;/strong&gt;: &lt;a href="https://pypi.org/" rel="noopener noreferrer"&gt;PyPI&lt;/a&gt; for publishing the production-ready package. Before that, I tested it on &lt;a href="https://test.pypi.org/" rel="noopener noreferrer"&gt;TestPyPI&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These tools are industry standards for Python projects, and their documentation provided helpful guidance.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Release Process
&lt;/h2&gt;

&lt;p&gt;Here’s how I took &lt;strong&gt;Code Complexity Pro&lt;/strong&gt; from development to release:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Tagging the Release&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I created an annotated tag to mark the release version using Git:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; git tag &lt;span class="nt"&gt;-a&lt;/span&gt; v1.1.2 &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Final production release of Code Complexity Pro"&lt;/span&gt;
 git push &lt;span class="nt"&gt;--follow-tags&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Tags allowed me to fix a version snapshot in the repository for easy reference.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Building the Package&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I used &lt;code&gt;setuptools&lt;/code&gt; to create source (&lt;code&gt;.tar.gz&lt;/code&gt;) and wheel (&lt;code&gt;.whl&lt;/code&gt;) distributions:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; python setup.py sdist bdist_wheel
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;These files were stored in the &lt;code&gt;dist/&lt;/code&gt; directory.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Uploading to TestPyPI&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I first uploaded the package to &lt;a href="https://test.pypi.org/" rel="noopener noreferrer"&gt;TestPyPI&lt;/a&gt; for testing:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; twine upload &lt;span class="nt"&gt;--repository&lt;/span&gt; testpypi dist/&lt;span class="k"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;This step ensured the package was functional before going live on PyPI.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Publishing to PyPI&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After successful testing, I uploaded the package to the official &lt;a href="https://pypi.org/" rel="noopener noreferrer"&gt;PyPI&lt;/a&gt;:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; twine upload dist/&lt;span class="k"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Testing Installation&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I installed the package from PyPI on a clean environment to verify its functionality:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; pip &lt;span class="nb"&gt;install &lt;/span&gt;code-complexity-pro
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Challenges and How I Solved Them
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Keyring Errors During &lt;code&gt;twine upload&lt;/code&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Issue&lt;/strong&gt;: &lt;code&gt;twine&lt;/code&gt; threw a &lt;code&gt;NoKeyringError&lt;/code&gt; because my environment didn’t support the keyring backend.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: I bypassed the keyring by directly entering the PyPI API token when prompted. Additionally, I configured a &lt;code&gt;.pypirc&lt;/code&gt; file for future automation:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt; &lt;span class="nn"&gt;[pypi]&lt;/span&gt;
 &lt;span class="py"&gt;repository&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;https://upload.pypi.org/legacy/&lt;/span&gt;
 &lt;span class="py"&gt;username&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;__token__&lt;/span&gt;
 &lt;span class="py"&gt;password&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;your-api-token&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. &lt;code&gt;ModuleNotFoundError&lt;/code&gt; in Tests
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Issue&lt;/strong&gt;: My test files couldn’t locate modules due to incorrect import paths.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: I updated all test imports to use fully qualified paths, e.g.,:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;code_complexity_pro.api_handler&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;send_code_to_groq&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Feedback from User Testing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;During testing, it became apparent that lab patner was unsure how to set up API keys. To address this, I added detailed instructions to the &lt;code&gt;README.md&lt;/code&gt; on configuring keys via &lt;code&gt;.env&lt;/code&gt; or a TOML file.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. 403 Forbidden on PyPI Upload
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Issue&lt;/strong&gt;: PyPI rejected uploads due to invalid authentication.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solution&lt;/strong&gt;: I regenerated an API token on PyPI and used it in the &lt;code&gt;.pypirc&lt;/code&gt; configuration file.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Packaging is Critical&lt;/strong&gt;: Preparing a project for release requires thoughtful structuring of files, dependencies, and configurations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentation Matters&lt;/strong&gt;: Clear, step-by-step instructions in the &lt;code&gt;README.md&lt;/code&gt; can prevent user confusion and ensure smooth adoption.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing is Invaluable&lt;/strong&gt;: Testing the package in environments similar to a user’s setup revealed issues I wouldn’t have caught otherwise.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Changes Made for the Release
&lt;/h2&gt;

&lt;p&gt;To prepare the project for release:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Added a &lt;code&gt;setup.py&lt;/code&gt; file for packaging.&lt;/li&gt;
&lt;li&gt;Created a &lt;code&gt;.pypirc&lt;/code&gt; file for easier uploads to PyPI.&lt;/li&gt;
&lt;li&gt;Updated &lt;code&gt;README.md&lt;/code&gt; with installation instructions, usage examples, and API key setup.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How Users Can Install and Use Code Complexity Pro
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;p&gt;To install the latest version of &lt;strong&gt;Code Complexity Pro&lt;/strong&gt;, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;code-complexity-pro&lt;span class="o"&gt;==&lt;/span&gt;1.1.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Usage
&lt;/h3&gt;

&lt;p&gt;Analyze code complexity with the following commands:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Analyze a Single File&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   code_complexity_pro &lt;span class="nt"&gt;--files&lt;/span&gt; path/to/file.py &lt;span class="nt"&gt;--api-key&lt;/span&gt; your-api-key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Analyze a Directory&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   code_complexity_pro &lt;span class="nt"&gt;--files&lt;/span&gt; /path/to/directory/ &lt;span class="nt"&gt;--api-key&lt;/span&gt; your-api-key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Save Results to a File&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   code_complexity_pro &lt;span class="nt"&gt;--files&lt;/span&gt; file.py &lt;span class="nt"&gt;--output&lt;/span&gt; analysis_results.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more detailed instructions, check the &lt;a href="https://github.com/MadhurSaluja/Release-0.1" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Completing Lab 9 was a challenging but rewarding experience. It gave me a deeper appreciation for the release process and taught me how to ensure that users can install and use a project effortlessly. By improving documentation, refining configurations, and addressing user feedback, &lt;strong&gt;Code Complexity Pro&lt;/strong&gt; is now a polished tool ready for the Python ecosystem.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Setting Up CI and Writing Tests for Collaborative Development</title>
      <dc:creator>madhur Saluja</dc:creator>
      <pubDate>Wed, 20 Nov 2024 04:45:18 +0000</pubDate>
      <link>https://dev.to/msaluja/setting-up-ci-and-writing-tests-for-collaborative-development-48g6</link>
      <guid>https://dev.to/msaluja/setting-up-ci-and-writing-tests-for-collaborative-development-48g6</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this post, I summarize my experience setting up GitHub Actions for Continuous Integration (CI), writing tests for my own project, and contributing to a partner's repository.&lt;/p&gt;




&lt;h2&gt;
  
  
  Setting Up GitHub Actions for My Project
&lt;/h2&gt;

&lt;p&gt;To automate testing and linting, I created a CI workflow in &lt;code&gt;.github/workflows/ci.yml&lt;/code&gt;. Below is the YAML configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Python CI&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout repository&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up Python&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-python@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;python-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.9'&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;python -m pip install --upgrade pip&lt;/span&gt;
          &lt;span class="s"&gt;pip install -r requirements.txt&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run linting&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;pip install black flake8&lt;/span&gt;
          &lt;span class="s"&gt;black . --check&lt;/span&gt;
          &lt;span class="s"&gt;flake8&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run tests&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;pytest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Challenges Faced
&lt;/h2&gt;

&lt;p&gt;While setting up CI, I encountered issues with YAML indentation and ensuring that tools like flake8 and black worked well together. Debugging these problems taught me how important it is to have consistent configurations across tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Outcome
&lt;/h2&gt;

&lt;p&gt;With CI in place, every commit is automatically tested, and I receive instant feedback on potential issues. This has significantly improved the reliability and maintainability of my project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing Tests for My Partner’s Repository
&lt;/h2&gt;

&lt;p&gt;I collaborated on AutoCommentingTool, a JavaScript-based project. Writing tests for someone else’s project was a unique experience and helped me understand the importance of clear documentation and modular code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Differences
&lt;/h2&gt;

&lt;p&gt;My Project: Python-based with pytest, black, and flake8.&lt;br&gt;
Partner’s Project: JavaScript-based with Mocha, Chai, and Sinon.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tests Written
&lt;/h2&gt;

&lt;p&gt;I focused on testing file operations (writeIntoFile) and contributed additional test cases for edge cases such as empty strings, nested paths, and handling write failures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Here’s a test I wrote for file operations in the repository:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;it('should throw an error if writing to the file fails', async function () {&lt;/span&gt;
    &lt;span class="s"&gt;const testData = 'This is a test comment.';&lt;/span&gt;
    &lt;span class="s"&gt;const testFileName = 'testOutput.js';&lt;/span&gt;

    &lt;span class="s"&gt;writeFileStub.yields(new Error('Write failed'));&lt;/span&gt;

    &lt;span class="s"&gt;try {&lt;/span&gt;
        &lt;span class="s"&gt;await writeIntoFile(testData, testFileName);&lt;/span&gt;
        &lt;span class="s"&gt;throw new Error('Expected error was not thrown');&lt;/span&gt;
    &lt;span class="s"&gt;} catch (err) {&lt;/span&gt;
        &lt;span class="s"&gt;expect(err.message).to.equal('Write failed');&lt;/span&gt;
    &lt;span class="s"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="s"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Challenges Faced
&lt;/h2&gt;

&lt;p&gt;Understanding unfamiliar code and framework setups.&lt;br&gt;
Adjusting to a different language (JavaScript) and testing tools (Mocha/Chai).&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;p&gt;A well-documented project is crucial for onboarding contributors.&lt;br&gt;
Writing modular and testable code makes it easier for others to add tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reflections on CI
&lt;/h2&gt;

&lt;p&gt;Setting up CI and experiencing its benefits firsthand has transformed how I approach development. Here’s what I learned:&lt;/p&gt;

&lt;p&gt;Time Savings: Automating tests saves time by catching issues early.&lt;br&gt;
Quality Assurance: CI enforces consistency and ensures that only well-tested code is merged.&lt;/p&gt;

&lt;p&gt;Collaboration: CI simplifies collaboration by providing a clear picture of the project’s health.&lt;/p&gt;

&lt;p&gt;I now see CI as an essential part of software development. It might take time to set up, but the benefits outweigh the initial effort.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This project was a valuable learning experience that improved my understanding of CI, testing, and collaboration. Setting up CI for my project made it more reliable, while contributing to a partner’s project helped me grow as a developer.&lt;/p&gt;

&lt;p&gt;I look forward to applying these skills in future projects and advocating for the use of CI in team settings to improve code quality and collaboration.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Writing Effective Tests for My Code Complexity Analyzer: A Deep Dive</title>
      <dc:creator>madhur Saluja</dc:creator>
      <pubDate>Sun, 10 Nov 2024 03:28:52 +0000</pubDate>
      <link>https://dev.to/msaluja/writing-effective-tests-for-my-code-complexity-analyzer-a-deep-dive-d02</link>
      <guid>https://dev.to/msaluja/writing-effective-tests-for-my-code-complexity-analyzer-a-deep-dive-d02</guid>
      <description>&lt;p&gt;Testing is an essential part of software development that often takes a back seat to feature building. But as I recently learned, good tests do more than just catch bugs—they make your code resilient, modular, and a lot easier to maintain. In this post, I’ll walk through my recent experience setting up and running tests for my Code Complexity Analyzer project, including which tools I used, how I tackled mocking responses from a Large Language Model (LLM) API, and the lessons I picked up along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing a Testing Framework and Tools
&lt;/h2&gt;

&lt;p&gt;For this project, I chose the following tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://docs.pytest.org/" rel="noopener noreferrer"&gt;pytest&lt;/a&gt;&lt;/strong&gt;: A powerful testing framework for Python, pytest is flexible and easy to use, with a large community and plenty of plugins. Its clear syntax and support for complex testing scenarios made it a natural choice for this project.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://pypi.org/project/pytest-watch/" rel="noopener noreferrer"&gt;pytest-watch&lt;/a&gt;&lt;/strong&gt;: To speed up development, pytest-watch automatically re-runs tests when files change. This tool has proven invaluable for TDD (Test-Driven Development) workflows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each tool serves a unique role in the testing process. While &lt;code&gt;pytest&lt;/code&gt; is the main framework, &lt;code&gt;pytest-watch&lt;/code&gt; allows for an efficient feedback loop when running tests. Using these tools in combination helped create a seamless and effective testing environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up the Tools
&lt;/h2&gt;

&lt;p&gt;Here’s how I set up these tools in my project:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Install and Configure&lt;/strong&gt;: I added &lt;code&gt;pytest&lt;/code&gt; and &lt;code&gt;pytest-watch&lt;/code&gt; to the project’s &lt;code&gt;requirements.txt&lt;/code&gt; file. This ensured that any developer working on the project could install them easily. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Using the Makefile&lt;/strong&gt;: I added targets in the &lt;code&gt;Makefile&lt;/code&gt; for running all tests, running a single test, and automatically rerunning tests on file changes. Here’s a snippet of the &lt;code&gt;Makefile&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;   &lt;span class="nl"&gt;test&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;$(&lt;/span&gt;TEST_RUNNER&lt;span class="p"&gt;)&lt;/span&gt;
    pytest
    &lt;span class="c"&gt;# Run a specific test file or function&lt;/span&gt;
    test-one:
        &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;&lt;span class="s2"&gt;TEST&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
            &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Please specify a test file or function with TEST=&amp;lt;file&amp;gt;::&amp;lt;function&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
            pytest &lt;span class="p"&gt;$(&lt;/span&gt;TEST&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="k"&gt;fi&lt;/span&gt;
    &lt;span class="c"&gt;# Automatically rerun tests on file changes&lt;/span&gt;
    watch:
        &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Watching for file changes... Press Ctrl+C to stop."&lt;/span&gt;
        &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="k"&gt;while &lt;/span&gt;inotifywait &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; modify,create,delete ./&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
            clear&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
            pytest&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these commands, I could easily run all tests, target specific tests, and set up an automatic test rerun on file changes. This setup kept my workflow fast and the codebase reliable as I iterated on the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mocking LLM Responses
&lt;/h2&gt;

&lt;p&gt;One of the unique challenges of this project was dealing with responses from an external LLM API. Testing directly against the live API would be slow, brittle, and dependent on network stability and API credits. Instead, I used mocking.&lt;/p&gt;

&lt;p&gt;To simulate API responses, I used &lt;code&gt;unittest.mock&lt;/code&gt; in &lt;code&gt;pytest&lt;/code&gt; to mock the HTTP responses from the LLM API. This way, I could control the response data and ensure that tests would run consistently. &lt;br&gt;
This approach allowed me to simulate both successful and error responses from the API, testing how the code handles different scenarios without relying on real API calls.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning from the Testing Process
&lt;/h2&gt;

&lt;p&gt;Writing test cases made me think critically about my code’s structure and exposed areas for improvement. For example, I initially designed the code with a CLI focus, but breaking down functionality into smaller, testable functions improved test coverage and made the code more modular and maintainable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Takeaways and "Aha!" Moments
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Testing Forces Modular Design&lt;/strong&gt;: Splitting code into smaller, focused functions improved both the readability and testability of my code. I had to rework some of my initial code to create functions that were easier to test, and this made the project more flexible and reliable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Edge Cases Matter&lt;/strong&gt;: Testing exposed edge cases I hadn’t considered initially, such as handling empty strings or invalid API keys. Mocking responses let me simulate these cases effectively, which highlighted how the code would handle real-world scenarios and prevented potential bugs from going unnoticed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Power of Automation&lt;/strong&gt;: Using &lt;code&gt;pytest-watch&lt;/code&gt; to automatically rerun tests on file changes streamlined my workflow. Tools like these are game-changers for productivity, and I plan to use them in all future projects.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Bugs and Surprises
&lt;/h3&gt;

&lt;p&gt;During testing, I discovered a few minor bugs, particularly around error handling. For instance, without a valid API key or with a misconfigured endpoint, the code initially didn’t handle the error gracefully. Adding tests forced me to write better error messages and handle unexpected input more robustly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reflections and Future Testing Plans
&lt;/h2&gt;

&lt;p&gt;This project was a great introduction to automated testing for me. I’ve tested code before but usually informally, by manually running it and observing the output. This experience taught me the value of structured, automated testing. Testing ensures that each change improves the code without introducing new bugs, and it’s particularly important for team environments where multiple developers work on the same codebase.&lt;/p&gt;

&lt;p&gt;In the future, I’ll be much more intentional about writing tests early in the development process. Building testability into the design from the start and using tools like &lt;code&gt;pytest&lt;/code&gt; and &lt;code&gt;pytest-watch&lt;/code&gt; will save time and improve code quality in the long run.&lt;/p&gt;




&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;Automated testing might seem daunting at first, but the time saved and the peace of mind gained are invaluable. I hope this post helps other developers see the benefits of testing frameworks, and that my setup process offers a clear starting point for those looking to implement similar tools in their projects.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Simplifying Development with Automation and Consistency – Lab 6 Walkthrough</title>
      <dc:creator>madhur Saluja</dc:creator>
      <pubDate>Sun, 03 Nov 2024 04:40:07 +0000</pubDate>
      <link>https://dev.to/msaluja/simplifying-development-with-automation-and-consistency-lab-6-walkthrough-1do1</link>
      <guid>https://dev.to/msaluja/simplifying-development-with-automation-and-consistency-lab-6-walkthrough-1do1</guid>
      <description>&lt;p&gt;Welcome to the Lab 6 journey! This blog post covers everything I did to enhance the &lt;code&gt;Code Complexity Pro&lt;/code&gt; project by integrating automation, setting up a consistent code style, and making it super easy for any contributor to dive in. Let's explore the tools I used, why I chose them, and how they improve our workflow!&lt;/p&gt;




&lt;h2&gt;
  
  
  📌 Goal: A Consistent, Automated Development Environment
&lt;/h2&gt;

&lt;p&gt;When working on a project with multiple contributors, consistency is critical. Without a unified coding style and automated checks, code can become difficult to maintain and read. Lab 6 is all about establishing a consistent, automated environment using tools for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Code Formatting&lt;/strong&gt;: Enforcing a consistent style across the codebase.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linting&lt;/strong&gt;: Identifying coding issues early to ensure quality and readability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automation&lt;/strong&gt;: Simplifying repetitive tasks like formatting, testing, and installation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's dive into how I set up each part and why it’s important!&lt;/p&gt;




&lt;h3&gt;
  
  
  🔍 Step 1: Choosing Black as Our Code Formatter
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Why Black?&lt;/strong&gt;&lt;br&gt;
Black is an “uncompromising” code formatter for Python, meaning it enforces strict coding standards without much customization. This is a big plus since it keeps the codebase consistent without room for stylistic debates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What We Did&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Installed Black&lt;/strong&gt; in my project to automate code formatting and ensure consistent styling.&lt;/li&gt;
&lt;li&gt;Configured Black to format code with an 88-character line length, which is ideal for readability and matches industry standards.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: Now, whenever we save our files, Black ensures they are formatted to match the project’s style, which helps us avoid formatting-related commits and reviews.&lt;/p&gt;


&lt;h3&gt;
  
  
  🔍 Step 2: Adding Flake8 as Our Linter
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Why Flake8?&lt;/strong&gt;&lt;br&gt;
Flake8 is a popular linter that checks for PEP 8 compliance and other common Python coding issues. It identifies syntax errors, unused imports, and other problems that can make code error-prone or harder to read.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What We Did&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Configured Flake8&lt;/strong&gt; to run automatically and check our code.&lt;/li&gt;
&lt;li&gt;Set up Flake8 to match Black’s line length (88 characters) to avoid conflicts.&lt;/li&gt;
&lt;li&gt;Ignored certain rules that overlap with Black’s formatting to streamline our setup.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: Flake8 helps us catch small issues before they become big problems, improving code quality while we work.&lt;/p&gt;


&lt;h3&gt;
  
  
  🔍 Step 3: Creating a .blackignore File
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Why .blackignore?&lt;/strong&gt;&lt;br&gt;
The &lt;code&gt;.blackignore&lt;/code&gt; file allows us to specify files and folders that we don’t want Black to format. This is useful for excluding version control folders, virtual environments, and other files that don’t require formatting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What We Did&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Created a &lt;code&gt;.blackignore&lt;/code&gt; file in the root of the project and added directories to exclude from formatting, such as:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  # .blackignore
  .git/
  __pycache__/
  venv/
  .venv/
  build/
  dist/
  .vscode/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: Black now ignores these folders, focusing only on the source code we are actively developing, which speeds up formatting and keeps the output clean.&lt;/p&gt;


&lt;h3&gt;
  
  
  🔍 Step 4: Automating with a Makefile
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Why a Makefile?&lt;/strong&gt;&lt;br&gt;
A Makefile is a convenient way to bundle common tasks into simple commands. Instead of running multiple commands manually, we can use &lt;code&gt;make&lt;/code&gt; commands to format, lint, test, and install dependencies with ease.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What We Did&lt;/strong&gt;:&lt;br&gt;
We created a &lt;code&gt;Makefile&lt;/code&gt; with the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nl"&gt;format&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    black .

&lt;span class="nl"&gt;lint&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    flake8 .

&lt;span class="nl"&gt;test&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    pytest

&lt;span class="nl"&gt;install&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;make format&lt;/code&gt;&lt;/strong&gt;: Runs Black to format all code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;make lint&lt;/code&gt;&lt;/strong&gt;: Runs Flake8 to check for code issues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;make test&lt;/code&gt;&lt;/strong&gt;: Runs tests to ensure everything works.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;make install&lt;/code&gt;&lt;/strong&gt;: Installs dependencies from &lt;code&gt;requirements.txt&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: With this Makefile, contributors can easily follow project standards by using simple commands.&lt;/p&gt;




&lt;h3&gt;
  
  
  🔍 Step 5: Setting Up Editor Integration with &lt;code&gt;.vscode/settings.json&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Why Editor Integration?&lt;/strong&gt;&lt;br&gt;
Automating formatting and linting within the editor helps maintain code standards in real-time. When settings are applied universally in &lt;code&gt;.vscode/settings.json&lt;/code&gt;, all contributors using VS Code get the same experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What We Did&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Created a &lt;code&gt;.vscode/settings.json&lt;/code&gt; file to enforce the same setup across contributors.&lt;/li&gt;
&lt;li&gt;Configured settings to automatically format with Black and lint with Flake8.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"python.formatting.provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"black"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"editor.formatOnSave"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"python.linting.flake8Enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"python.linting.enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"python.formatting.blackArgs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"--line-length"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"88"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"python.linting.flake8Args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"--max-line-length=88"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"--ignore=E203,E266,E501,W503"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"files.exclude"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"**/__pycache__"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"**/.git"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"**/.vscode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"**/venv"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: This setup ensures that formatting and linting happen automatically, so contributors don’t have to remember to run them manually.&lt;/p&gt;


&lt;h3&gt;
  
  
  🔍 Step 6: Adding a Git Pre-Commit Hook
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Why a Pre-Commit Hook?&lt;/strong&gt;&lt;br&gt;
Pre-commit hooks automatically run checks before changes are committed. This ensures that any code added to the repository adheres to our formatting and linting rules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What We Did&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Installed &lt;code&gt;pre-commit&lt;/code&gt; and set it up to run Black and Flake8 before each commit.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To set up &lt;code&gt;pre-commit&lt;/code&gt;, we added a &lt;code&gt;.pre-commit-config.yaml&lt;/code&gt; file with the following configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .pre-commit-config.yaml&lt;/span&gt;
&lt;span class="na"&gt;repos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://github.com/psf/black&lt;/span&gt;
    &lt;span class="na"&gt;rev&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;22.3.0&lt;/span&gt;  &lt;span class="c1"&gt;# Use the latest Black version&lt;/span&gt;
    &lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;black&lt;/span&gt;
        &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--line-length"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;88"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://github.com/pycqa/flake8&lt;/span&gt;
    &lt;span class="na"&gt;rev&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;4.0.1&lt;/span&gt;  &lt;span class="c1"&gt;# Use the latest Flake8 version&lt;/span&gt;
    &lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;flake8&lt;/span&gt;
        &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--max-line-length=88"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--ignore=E203,E266,E501,W503"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After creating the config file, we ran:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pre-commit &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: Now, every time we make a commit, Black and Flake8 run automatically, preventing non-compliant code from being committed.&lt;/p&gt;




&lt;h3&gt;
  
  
  🔍 Step 7: Cleaning Up Commits with Git Rebase and Squash
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Why Rebase and Squash?&lt;/strong&gt;&lt;br&gt;
When working on a feature branch, it’s easy to end up with multiple commits. Squashing commits into a single one makes the commit history cleaner, making it easier to review and track changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What We Did&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Used &lt;code&gt;git rebase -i&lt;/code&gt; to squash all commits on the &lt;code&gt;lab6&lt;/code&gt; branch into one.&lt;/li&gt;
&lt;li&gt;Merged the squashed commit into &lt;code&gt;main&lt;/code&gt; and pushed it to GitHub.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: Our commit history is now clean, making it easy to track the single, consolidated change for Lab 6.&lt;/p&gt;




&lt;h3&gt;
  
  
  📘 Final Thoughts
&lt;/h3&gt;

&lt;p&gt;In Lab 6, I set up a unified, automated workflow that enforces consistent formatting, catches errors early, and streamlines collaboration. Contributors can now easily follow project standards, making the codebase cleaner and easier to maintain.&lt;/p&gt;

&lt;p&gt;I hope this setup will help keep Code Complexity Pro organized and welcoming to new contributors. Happy coding! 🚀&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Hacktoberfest Adventure with `react-chatbotify`: From Shifted Issues to Success! 🎉</title>
      <dc:creator>madhur Saluja</dc:creator>
      <pubDate>Thu, 31 Oct 2024 23:49:49 +0000</pubDate>
      <link>https://dev.to/msaluja/hacktoberfest-adventure-with-react-chatbotify-from-shifted-issues-to-success-19g8</link>
      <guid>https://dev.to/msaluja/hacktoberfest-adventure-with-react-chatbotify-from-shifted-issues-to-success-19g8</guid>
      <description>&lt;p&gt;For my last Hacktoberfest contribution, I tackled an issue with &lt;a href="https://github.com/tjtanjin/react-chatbotify/issues/223" rel="noopener noreferrer"&gt;&lt;code&gt;react-chatbotify&lt;/code&gt;&lt;/a&gt;, which was a thrilling shift from my original assignment. I initially had another issue, but after two weeks without hearing back from the project owner, I decided it was time for a new challenge. That’s how I stumbled upon issue #223, which was all about supercharging the ChatBotLoader component with new tests. Let’s dive in! 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  💥 The Issue at Hand
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/tjtanjin/react-chatbotify/issues/223" rel="noopener noreferrer"&gt;issue #223&lt;/a&gt; was a call to action for expanding test coverage on the ChatBotLoader component. This component is like the bot's brain loader—it initializes key configurations, styles, themes, and plugins. The goal? To make sure this component performs flawlessly in every scenario!&lt;/p&gt;

&lt;h2&gt;
  
  
  🔧 Getting Set Up
&lt;/h2&gt;

&lt;p&gt;My first task was setting up the local environment to run the &lt;code&gt;react-chatbotify&lt;/code&gt; repository smoothly. I peeked into existing tests to understand the project’s testing structure, and it clicked. Once I got the hang of it, I was ready to take on the ChatBotLoader. Even though I was initially assigned to a different issue, I quickly adapted to this new one—it was refreshing and pushed me to learn a lot!&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 What I Learned
&lt;/h2&gt;

&lt;p&gt;This issue was a treasure trove of learning opportunities, especially around testing components that use multiple contexts and props in React. The ChatBotLoader, in particular, interacts with various contexts like &lt;code&gt;BotRefsContext&lt;/code&gt;, &lt;code&gt;BotStatesContext&lt;/code&gt;, and more. I needed to mock these contexts to keep the tests isolated and to focus on the component's behavior. &lt;/p&gt;

&lt;p&gt;I also had a fun encounter with the &lt;code&gt;emitRcbEvent&lt;/code&gt; function and &lt;code&gt;RcbEvent.PRE_LOAD_CHATBOT&lt;/code&gt; (sounds fancy, right? 😆). This allowed me to dive into event testing, both before and after configuration loading.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧩 Breaking Down the Code Fix
&lt;/h2&gt;

&lt;p&gt;Here's a high-level breakdown of each test I worked on:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;🔗 Flow Reference Update&lt;/strong&gt;: This test made sure the &lt;code&gt;flowRef&lt;/code&gt; updates correctly with the given flow prop. By mocking &lt;code&gt;flowRef&lt;/code&gt; and verifying that it received the correct flow data, the test proved that the component properly sets up the flow.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;🚀 Pre-Load Event Emission&lt;/strong&gt;: This test checked that the &lt;code&gt;rcbPreLoadChatBot&lt;/code&gt; event fired just before the configuration load. Mocking the function’s return allowed me to simulate this event and verify &lt;code&gt;emitRcbEvent&lt;/code&gt; was doing its thing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;🎨 Theme Change Reloads Config&lt;/strong&gt;: Here, I added a new theme to the list and watched for the config reload. This test checks how the component reacts to prop changes, ensuring that every time a new theme is introduced, the component reloads.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;🎉 Post-Load Event Emission&lt;/strong&gt;: Similar to the pre-load event, this one verified that &lt;code&gt;rcbPostLoadChatBot&lt;/code&gt; triggered after the configuration loaded successfully, giving it a nice little “thumbs up” for a job well done. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  💡 Challenges &amp;amp; Research
&lt;/h2&gt;

&lt;p&gt;I have to admit, working with &lt;code&gt;emitRcbEvent&lt;/code&gt; threw a few curveballs. The &lt;code&gt;defaultPrevented&lt;/code&gt; attribute required special attention, and I had to mock return values to make sure everything interacted correctly. &lt;/p&gt;

&lt;p&gt;And of course, mocking hooks and services to test the component without breaking it required some serious sleuthing. I went down a few rabbit holes researching testing techniques, especially around context-heavy components, but it was worth every second.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎯 Final Thoughts &amp;amp; Next Steps
&lt;/h2&gt;

&lt;p&gt;I’m waiting for the green light from the project owner to make sure these tests hit the mark. As soon as I get the nod, I'll submit my PR here - Add unit tests for ChatBotLoader (link to come!). &lt;/p&gt;

&lt;h3&gt;
  
  
  The Takeaway
&lt;/h3&gt;

&lt;p&gt;Working on this issue showed me the flexibility needed in open-source projects. Switching from one issue to another, adjusting to unfamiliar code, and learning new testing methods all made this journey one for the books. I’m already pumped for the next adventure!&lt;/p&gt;




&lt;p&gt;Thanks for following along, and here's to many more coding quests! 🎉👨‍💻👩‍💻&lt;/p&gt;

</description>
    </item>
    <item>
      <title>A Fun Take on Enhancing the Meal Selector CLI Tool</title>
      <dc:creator>madhur Saluja</dc:creator>
      <pubDate>Thu, 31 Oct 2024 19:08:48 +0000</pubDate>
      <link>https://dev.to/msaluja/a-fun-take-on-enhancing-the-meal-selector-cli-tool-491j</link>
      <guid>https://dev.to/msaluja/a-fun-take-on-enhancing-the-meal-selector-cli-tool-491j</guid>
      <description>&lt;p&gt;Working on a Meal Selector CLI Tool sounded like a quick and easy project, right? A simple random meal generator, ideal for those indecisive days. However, as I dove into the details, I thought, “Why not make it even more interesting?” And that’s how we ended up enhancing this tool to not only provide meal suggestions but also to make it calorie-conscious for users with specific dietary goals. This turned out to be a great little upgrade that combined utility with a touch of personalization.&lt;/p&gt;

&lt;p&gt;Here’s a look at how I took on &lt;a href="https://github.com/sumanth-0/100LinesOfPythonCode/issues/105#event-14920349001" rel="noopener noreferrer"&gt;Issue #105&lt;/a&gt; and added some fun, useful features along the way. Let’s dive in!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Initial Idea
&lt;/h2&gt;

&lt;p&gt;The original concept for the Meal Selector CLI Tool was straightforward: randomly pick an appetizer, main course, and dessert from predefined lists and serve up a meal suggestion for the day. It’s a great idea for people who love variety or just can’t decide on what to eat! The first version was designed to keep things simple, offering a random meal suggestion each time the script runs.&lt;/p&gt;

&lt;h2&gt;
  
  
  But Wait, Let’s Add Some Calorie Control!
&lt;/h2&gt;

&lt;p&gt;As I was working on the basic setup, an idea popped up: what if users could specify how many calories they want for the day, and the tool could create a meal that meets (or at least stays under) that target? This led to adding a few new features, which made the tool not only a meal generator but also a mini dietary planner!&lt;/p&gt;

&lt;p&gt;In came the &lt;strong&gt;calorie-based meal selection feature&lt;/strong&gt;. Each food item got an associated calorie count, which meant that our list of items became slightly more sophisticated but added a ton of value for users. Now, users could enter a target calorie count, and the tool would generate a meal that met their requirements. A few tests, some debugging, and voila — we had a calorie-aware meal selector!&lt;/p&gt;

&lt;h2&gt;
  
  
  Minimum Calorie Requirement: No More 100-Calorie Days
&lt;/h2&gt;

&lt;p&gt;One quick snag we encountered was when users entered very low calorie limits, like 100 or 200. Obviously, generating a full meal with such low calories isn’t realistic, so we added a &lt;strong&gt;minimum calorie notification&lt;/strong&gt;. The tool now calculates the lowest possible calorie count for a meal (based on the least calorie-dense items) and prompts users to enter a number above this minimum if they go too low.&lt;/p&gt;

&lt;p&gt;This way, the tool ensures a more enjoyable (and realistic) user experience by making sure the calorie goal is achievable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Final Touches: Visual Appeal and User Guidance
&lt;/h2&gt;

&lt;p&gt;To make the tool even more enjoyable to use, I added some color-coded output using the &lt;code&gt;colorama&lt;/code&gt; library. Each part of the meal is displayed with its name and calorie count, alongside a total calorie tally. This makes the output not only functional but also visually appealing, giving users a more engaging experience.&lt;/p&gt;

&lt;p&gt;On top of that, the error handling was refined to guide users smoothly through the tool, especially when inputting calorie limits. All these updates came together to provide a tool that’s both simple and fun to use — and more useful than just a basic randomizer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping It Up
&lt;/h2&gt;

&lt;p&gt;So there you have it! What started as a simple 100-lines-of-code project turned into a feature-rich, personalized meal suggestion tool. With Issue #105 resolved and the &lt;a href="https://github.com/sumanth-0/100LinesOfPythonCode/pull/247" rel="noopener noreferrer"&gt;PR #247&lt;/a&gt; merged, we now have a tool that not only picks a meal for you but also lets you stay mindful of your calorie intake.&lt;/p&gt;

&lt;p&gt;Next time you’re unsure what to eat, just fire up the Meal Selector CLI Tool, set your calorie goal, and let it surprise you. It’s a great example of how a small project can turn into something useful with just a few thoughtful additions. Happy meal planning!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Fixing Rounded Borders for Blog Previews: A Journey Through CSS and HTML</title>
      <dc:creator>madhur Saluja</dc:creator>
      <pubDate>Thu, 31 Oct 2024 18:57:46 +0000</pubDate>
      <link>https://dev.to/msaluja/fixing-rounded-borders-for-blog-previews-a-journey-through-css-and-html-f53</link>
      <guid>https://dev.to/msaluja/fixing-rounded-borders-for-blog-previews-a-journey-through-css-and-html-f53</guid>
      <description>&lt;h3&gt;
  
  
  &lt;a href="https://github.com/OpenElements/open-elements-website/issues/110" rel="noopener noreferrer"&gt;Issue #110: Round the Left Border of Blog Previews&lt;/a&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://github.com/OpenElements/open-elements-website/pull/123#event-14950823090" rel="noopener noreferrer"&gt;Pull Request #123&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;First off, a quick apology for the delay in getting this blog post out! This little task of rounding off a few borders took me on a grand tour through the codebase of OpenElements’ website. What started as a “simple” visual tweak quickly turned into a full-blown exploration. But hey, no challenge left unrounded, right?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Issue: Smooth and Rounded, All the Way Around
&lt;/h2&gt;

&lt;p&gt;Here’s the scoop: the blog previews on OpenElements are supposed to look neat and consistent, with rounded borders on all sides. But there was a hitch—the left border was stubbornly squared off! It may sound like a tiny detail, but design is all about the little things. So I rolled up my sleeves and dived in.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Journey: CSS, HTML, and the Quest for the Perfect Border
&lt;/h2&gt;

&lt;p&gt;To start, I combed through the &lt;code&gt;style.css&lt;/code&gt; file where most of the site’s styling lives. Since this wasn’t my usual haunt, I had to carefully review each class, container, and style that could possibly impact the blog previews’ borders. Think of it as a game of hide-and-seek, but with almost 5000 lines of code!&lt;/p&gt;

&lt;p&gt;The main challenge? Figuring out exactly where the left border styling was controlled. This meant cross-referencing and analyzing not only the CSS but also the HTML files like &lt;code&gt;list.html&lt;/code&gt; and &lt;code&gt;single.html&lt;/code&gt; that handled blog layouts. It was a code detective’s dream—or maybe nightmare—situation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: A Border Makeover
&lt;/h2&gt;

&lt;p&gt;After some back-and-forth, I pinpointed the right container and style that needed tweaking. It was just a small change in &lt;code&gt;style.css&lt;/code&gt;, but it made all the difference, ensuring the left border would finally match its rounded friends on the right.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing the Waters
&lt;/h2&gt;

&lt;p&gt;With the change in place, I hit refresh on every blog preview I could find to confirm everything was working as it should. Sure enough, the borders were finally rounded on all sides, giving the blog previews a smoother, more polished look. Mission accomplished!&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;p&gt;The big takeaway here? Even minor design adjustments can take you through a deep dive of a codebase, especially when it’s someone else’s project! This pull request gave me a chance to untangle and understand OpenElements’ styling setup, one line at a time. It’s all about getting the details just right, even if it takes a little extra time.&lt;/p&gt;

&lt;p&gt;Check out the full &lt;a href="https://github.com/OpenElements/open-elements-website/pull/123#event-14950823090" rel="noopener noreferrer"&gt;Pull Request here&lt;/a&gt; to see the updates in action!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
